题意:一共有256个像素格,你可以将这些像素格分组,每个分组小于等于K。
给出n个像素格,像素格以其所在分组内的一个像素表示,就是每个分组对应一个组名(像素格的数值),求给出的数的对应的组名的字典序最小的情况。
题解:
1、贪心,想办法在满足条件的情况下让相应的组名取得更小的值
2、分情况贪心,首先让所有的像素都未分组,然后按照给出的数一个一个地进行分组
3、最简单的情况就是该组已经被分到了某一组,那答案就是组名
4、选出max(0,p[i] - k + 1)到 p[i] 区间,判断区间左边是否被分组,或者是否独立成组。如果区间未分组或者独立成组(组名是自己),那么表示整个区间都可以表示为区间最左边的值(即整个区间成组)
5、依然选出如上区间,从右往左找到在区间内的一个分组,那么把区间有半部分都归入这个分组
6、如上区间,右往左找不到分组,就把整个区间都成组,组名为区间左边对应的值
#include <bits/stdc++.h> using namespace std; const int maxn = 260,maxm = 100000 + 10; int group[maxn],p[maxm]; int main() { int n,k,x; memset(group,-1,sizeof(group)); cin >> n >> k; for(int i = 0;i < n;i++) cin >> p[i]; for(int i = 0;i < n;i++) { if(group[p[i]] != -1) //该数字已经有所属组,直接输出组名 cout << group[p[i]] << " "; else { //该数字还没有分组 int j,tag = p[i] - k + 1; //tag表示可能区间左下标 tag = max(0,tag); //保证下标在正常范围 //区间左下标没有分组,那么直接让整个区间成组,组名等于左下标 if(group[tag] == tag || group[tag] == -1) { for(j = tag;j <= p[i];j++) group[j] = tag; cout << group[p[i]] << " "; } //区间左下标有分组并且组名不等于左下标 else { for(j = p[i];j >= tag;j--) //搜索区间内最右边的分组 if(group[j] != -1) break; if(group[j] > tag) tag = group[j]; //区间内存在分组,就让后半部分纳入该分组 else tag = j + 1; //区间内没有分组,让整个区间成组,组名等于左下标 for(j = tag;j <= p[i];j++) group[j] = tag; cout << group[p[i]] << " "; } } } return 0; }