题干:
Recently Monocarp got a job. His working day lasts exactly mm minutes. During work, Monocarp wants to drink coffee at certain moments: there are nn minutes a1,a2,…,ana1,a2,…,an, when he is able and willing to take a coffee break (for the sake of simplicity let's consider that each coffee break lasts exactly one minute).
However, Monocarp's boss doesn't like when Monocarp takes his coffee breaks too often. So for the given coffee break that is going to be on minute aiai, Monocarp must choose the day in which he will drink coffee during the said minute, so that every day at least dd minutes pass between any two coffee breaks. Monocarp also wants to take these nn coffee breaks in a minimum possible number of working days (he doesn't count days when he is not at work, and he doesn't take coffee breaks on such days). Take into account that more than dd minutes pass between the end of any working day and the start of the following working day.
For each of the nn given minutes determine the day, during which Monocarp should take a coffee break in this minute. You have to minimize the number of days spent.
Input
The first line contains three integers nn, mm, dd (1≤n≤2⋅105,n≤m≤109,1≤d≤m)(1≤n≤2⋅105,n≤m≤109,1≤d≤m) — the number of coffee breaks Monocarp wants to have, the length of each working day, and the minimum number of minutes between any two consecutive coffee breaks.
The second line contains nn distinct integers a1,a2,…,ana1,a2,…,an (1≤ai≤m)(1≤ai≤m), where aiai is some minute when Monocarp wants to have a coffee break.
Output
In the first line, write the minimum number of days required to make a coffee break in each of the nn given minutes.
In the second line, print nn space separated integers. The ii-th of integers should be the index of the day during which Monocarp should have a coffee break at minute aiai. Days are numbered from 11. If there are multiple optimal solutions, you may print any of them.
Examples
Input
4 5 3
3 5 1 2
Output
3
3 1 1 2
Input
10 10 1
10 5 7 4 6 3 2 1 9 8
Output
2
2 1 1 2 2 1 2 1 1 2
Note
In the first example, Monocarp can take two coffee breaks during the first day (during minutes 11 and 55, 33 minutes will pass between these breaks). One break during the second day (at minute 22), and one break during the third day (at minute 33).
In the second example, Monocarp can determine the day of the break as follows: if the minute when he wants to take a break is odd, then this break is on the first day, if it is even, then this break is on the second day.
题目大意:
最近Monocarp找到了一份工作。他的工作时间正好是m分钟。在工作期间,Monocarp想要在特定的时刻喝咖啡:有n分钟a1,a2,…,an,当他能够并且愿意喝咖啡休息(为了简单起见,让我们考虑一下每个咖啡休息时间正好持续1分钟)。
然而,Monocarp的老板不喜欢Monocarp经常喝咖啡休息时间。所以对于给定的咖啡休息时间是在分钟ai上,Monocarp必须选择他在这一分钟内喝咖啡的日期,以便在任何两个咖啡休息时间之间每天至少有d分钟的时间。Monocarp还希望在最短的工作日内享受这n个咖啡休息时间(他不计算他不工作的天数,而且他在这样的日子里不喝咖啡)。考虑到任何工作日结束到下一个工作日开始之间超过d分钟的时间。
在给定的n分钟内决定一天的时间,在这一分钟内单粒种子应该喝咖啡休息。你必须尽量减少花费的天数。
解题报告:
这题的题意确实是比较那懂,大致就是有某人要在n天内喝n杯咖啡(因为m貌似没啥用,因为就算每天只喝一杯,最多就用n天喝完啊),喝每杯咖啡都花费1单位时间,如果两杯咖啡在一天喝,那么它们之间至少要相隔d min,要求输出最少几天可以喝完,并输出对应题目输入的每一杯咖啡是在第几天喝的。
答案可以很多种但是我们只需要构造最好想的,我们可以贪心找出其中一组解。最早喝的那杯咖啡在某一天中一定是第一杯,我们就直接让它在第一天被喝,由此可以推出下一杯咖啡时间至少要 >= ai + d + 1,于是一直往下找即可,如果找不到就说明这一天已经不能喝了,另开一天即可。
AC代码:
#include
using namespace std;
const int MAX = 2e5 + 10;
const int INF = 0x3f3f3f3f;
int a[MAX],ans[MAX];
set > ss;
set > :: iterator it;
int n,m,d,cnt;
int main()
{
cin>>n>>m>>d;
for(int i = 1; i<=n; i++) {
scanf("%d",a+i);
ss.insert(make_pair(a[i],i));
}
while(!ss.empty()) {
int pos = ss.begin() -> second;
ans[pos] = ++cnt;
ss.erase(ss.begin());
while(1) {
it = ss.upper_bound(make_pair(a[pos]+d,INF));
if(it == ss.end()) break;
pos = it->second;
ans[pos] = cnt;
ss.erase(it);
}
}
printf("%d\n",cnt);
for(int i = 1; i<=n; i++) printf("%d%c",ans[i],i==n ? '\n' : ' ');
return 0;
}
总结:
还是提醒一些坑:
1.用了STL就一定要注意是否为空!it迭代器是否有效!这题巧了,不需要在while判断if(空了) break;因为你lowerbound或者upperbound的时候如果没找到(包括了set中已经没元素的情况了),都直接就是ss.end()了,所以这些情况直接包含在这里break了。
2.这种语句套路也很常用啊,while(不空) 搞第一个;while(1) 然后 set中二分 , if(it == ss.end()) break; 、、 ;类似这个意思。
3.关于pair和lowerbound。这题这么写it = ss.lower_bound(make_pair(a[pos] + d + 1,0));也可以,但是
it = ss.upper_bound(make_pair(a[pos] + d,0)); 就不行!!!这牵扯到set中对pair类型默认排序的问题。
你如果用upperbound , pair的second就必须用INF,或者一个特别大的数。不然就会wa。
如果是int类型的set,就没事。
set s;
set :: iterator itt;
s.insert(1);
s.insert(2);
s.insert(3);
itt = s.upper_bound(2);
cout << *itt; //输出3
但是pair类型,对于这个题。
3 3 1
1 2 3
这个样例就过不了。输出的就全是1,但是显然不符合题意。