题解:P14842 [ICPC 2022 Yokohama R] Hasty Santa Claus

题解:P14842 [ICPC 2022 Yokohama R] Hasty Santa Claus

思路解析:

这道题一看便知是一道贪心,我们思考贪心策略。

  1. 对初始顺序进行排序,第一关键字是开始时间与结束时间的差,第二关键字是开始时间,第三关键字是结束时间。
  2. 如果结束时间是所有结束时间的最大值,那最终的答案从大往小取,如果这个时间的次数不超过 \(k\),那就取,否则再判断下一个。
  3. 如果结束时间不是所有结束时间的最大值,最终答案从小往大取,步骤与是最大值的情况几乎一致。

代码实现的提醒:

  1. 一个时间的出现次数,可以开一个桶存。
  2. 写两个排序函数,一个是处理答案,一个是排序回原来的顺序。
  3. 写排序函数和判断时仔细一些。
#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;
}
posted @ 2026-01-11 17:22  Mirror_victor  阅读(0)  评论(0)    收藏  举报