专栏文章
题解:P13316 [GCJ 2012 #1A] Kingdom Rush
P13316题解参与者 3已保存评论 3
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @mingodwc
- 此快照首次捕获于
- 2025/12/02 02:07 3 个月前
- 此快照最后确认于
- 2025/12/02 02:07 3 个月前
背景
对不起审核大大,以前从来没写过题解,接连犯了好多错。。。
今年的普及组全机房就本蒟蒻没过呜呜,难受的我决定惩罚自己刷一百道题,结果一共就 AC 两道。。。但偶然间瞅到这道题居然可以写题解!!!
于是呢,就有了本蒟蒻的第一篇题解 hh。
分析
看到至少需要通关多少次,考虑排序和贪心。
使用两个结构体 和 分别存储关卡的两个难度条件, 数组记录每个关卡的完成状态(由于有多组数据,所以每次读取下一组数据时 数组要清零)。
排序
优先尝试完成第二条件要求的关卡(奖励更高),当第二条件不满足时,转而完成第一条件要求的关卡。
所以两颗星星的情况从小到大排就好啦,但一颗星星的情况要注意:定义一个 表示 Ryan 此时得到的星星数,如果 满足以一星的成绩通过下一关,就去判断能否以现有的 通过更高条件的以两星通过的关卡,否则就把剩下的关卡按照以一星完成所需的星星数从小到大排起来。
记得每次操作后重新排序剩余关卡,不然顺序就乱了。
贪心
使用双指针分别遍历两个排序后的关卡,实时更新当前所得的星星数 作为通关判断的依据,并且要记录每个关卡的完成进度 。
AC代码
CPP#include <bits/stdc++.h>
using namespace std;
const int N=1e3+5;
int t,sum,w[N];
struct one{
int _1,_2,id;
}l1[N];
struct two{
int _2,id;
}l2[N];
bool cmp1(one x,one y){
if(sum>=x._1&&sum>=y._1) return x._2>y._2;
return x._1<y._1;
}//1星
bool cmp2(two x,two y){
return x._2<y._2;
}//2星
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>t;
int k=0;
while(t--){
int n,ans=0;
sum=0;
cin>>n;
memset(w,0,sizeof(w));//清零
for(int i=1;i<=n;i++){
cin>>l1[i]._1>>l2[i]._2;
l1[i]._2=l2[i]._2;
l1[i].id=i;
l2[i].id=i;
}
sort(l1+1,l1+1+n,cmp1);//先排1星
sort(l2+1,l2+1+n,cmp2);//再排2星
int x1=1,x2=1;//开贪
bool f=0;
while(x2<=n){
bool _f=0;
if(sum>=l2[x2]._2){
sum+=(2-w[l2[x2].id]);
w[l2[x2].id]=2;
_f=1;
x2++;
ans++;
}else{
if(sum>=l1[x1]._1&&x1<=n){//这里卡了好久,一定要判断x1值域,不然会爆TAT
if(w[l1[x1].id]==0){
w[l1[x1].id]=1;
sum++;
ans++;
}
x1++;
_f=1;
}
}
sort(l1+x1,l1+1+n,cmp1);//重新排
if(!_f){
cout<<"Case #"<<++k<<": Too Bad\n";
f=1;
break;
}//此关卡无法通过
}
if(f) continue;
cout<<"Case #"<<++k<<": "<<ans<<"\n";//此关卡可通过
}
return 0;//完结撒花(OvO)
}
相关推荐
评论
共 3 条评论,欢迎与作者交流。
正在加载评论...