T168340 「TOCO Round 1」自适应 PVZ
思路:拿样例来解释请先看下面的图(本蒟蒻实属灵魂画手,画的不好请多多指教):
样例1
这里两个僵尸起始终止时间是独立的两个区间,不存在覆盖,所以一个豌豆射手就能干掉。
样例2
这里第一个射手需要攻击区间[1,3],第二个射手需要攻击区间[1,3],由于两个射手在第3只僵尸出现时都在攻击各自的僵尸,所以这只僵尸不能干掉
样例3
这里两个区间也无重叠,与样例1属一类。
从这里看出推出:我们如果m>=n,直接输出0(因为射手多每个打一个都能打完,这个优化能帮助我们白拿20分),接着对结束时间排序(早点打完早点继续),然后判断场上的豌豆射手(初始没有一个)能不能干掉该僵尸,如果能就修改这个豌豆射手的结束时间,否则就看看场下是否存在豌豆射手,如果有就派出,修改这个豌豆射手的结束时间,否则代表豌豆射手们一个都干不掉它了,故会走进房子,计数器++,然后还有一点,就是越晚结束的豌豆射手能打它就先让它打(这样如果接下来的僵尸出现的很早,就能保留早结束的豌豆射手干它,如你现在有结束时间2、1、4的两个豌豆射手,那么假设先来一个起始时间是4的僵尸,再来了一个起始时间是2的僵尸,,然后来了一个起始时间是1的僵尸那么我们如果不排序,就会让一只僵尸走进房子),然后这样我们能拿80分,100分的代码要用到map的一种功能,本蒟蒻殊不知!
奉上代码
#include<bits/stdc++.h>
using namespace std;
int n,m,total,a[200001],i,j,ans;
struct zombie{
int l,r;
}z[200001];
bool cmp(zombie x,zombie y){
return x.r<y.r;
}
int main(){
scanf("%d%d",&n,&m);
if(m>=n){
printf("0");
return 0;
}
for(i=1;i<=n;i++)
scanf("%d%d",&z[i].l,&z[i].r);
sort(z+1,z+1+n,cmp);
for(i=1;i<=n;i++){
for(j=total;j>=1;j--){
if(a[j]<=z[i].l){
a[j]=z[i].r;
break;
}
}
if(j==0){
total++;
if(total>m){
total=m;
ans++;
continue;
}
a[total]=z[i].r;
}
sort(a+1,a+1+total);
}
printf("%d",ans);
return 0;
}