题解:P14842 [ICPC 2022 Yokohama R] Hasty Santa Claus
题解:P14842 [ICPC 2022 Yokohama R] Hasty Santa Claus
思路解析:
这道题一看便知是一道贪心,我们思考贪心策略。
- 对初始顺序进行排序,第一关键字是开始时间与结束时间的差,第二关键字是开始时间,第三关键字是结束时间。
- 如果结束时间是所有结束时间的最大值,那最终的答案从大往小取,如果这个时间的次数不超过 \(k\),那就取,否则再判断下一个。
- 如果结束时间不是所有结束时间的最大值,最终答案从小往大取,步骤与是最大值的情况几乎一致。
代码实现的提醒:
- 一个时间的出现次数,可以开一个桶存。
- 写两个排序函数,一个是处理答案,一个是排序回原来的顺序。
- 写排序函数和判断时仔细一些。
#include<bits/stdc++.h>
#define int long long
using namespace std;
struct node {
// z 是结果,方便输出。
// c 时开始时间与结束时间的差。
int a,b,z,xh,c;
}a[1010];
// 记录这个时间的次数。
int b[1010];
// 排序函数,第一关键字是差,第二关键字是开始,第三关键字是结束。
bool cmp(node x,node y) {
if(x.c==y.c) {
if(x.a==y.a) {
return x.b<y.b;
}
return x.a<y.a;
}
return x.c<y.c;
}
// 按照序号排序回到原来的顺序。
bool cmp1(node x,node y) {
return x.xh<y.xh;
}
signed main(){
int n,k,ma=INT_MIN;
cin>>n>>k;
for(int i=1;i<=n;i++) {
cin>>a[i].a>>a[i].b;
a[i].xh=i;
a[i].c=a[i].b-a[i].a+1;
ma=max(ma,a[i].b);
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++) {
//cout<<a[i].a<<" "<<a[i].b<<"\n";
// 如果结束时间是最大值,结果从大往小数。
if(a[i].b==ma) {
for(int j=a[i].b;j>=a[i].a;j--) {
if(b[j]<k) {
b[j]++;
a[i].z=j;
break;
}
}
continue;
}
// 否则,结果从小往大数。
for(int j=a[i].a;j<=a[i].b;j++) {
if(b[j]<k) {
b[j]++;
a[i].z=j;
break;
}
}
// if(a[i].z==0) {
// cout<<i<<" poki\n";
// }
//cout<<a[i].z<<"\n";
}
sort(a+1,a+n+1,cmp1);
for(int i=1;i<=n;i++) {
cout<<a[i].z<<"\n";
}
return 0;
}

浙公网安备 33010602011771号