题意:一共有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;
}