CF733C[Epidemic in Monstropolis]题解
Darling_ZX · · 题解
分析题意:
读题后易得,题意无非是将
解决代码部分:
分析完题意后,不要着急,分模块写,想清楚自己的思路,同时也方便调试。
1.预处理读入部分:
读入部分没什么好说的,定义
以下为部分代码:
n=read();
for(int i=1;i<=n;i++){
a[i]=read();
asum+=a[i];
}
m=read();
for(int i=1;i<=m;i++){
b[i]=read();
bsum+=b[i];
}
if(asum!=bsum){ //如果两数组元素和不相等 则无解情况
puts("NO");
return 0;
}
2.将 a_i 分为 k 段:
注意一些细节处理,此处变量多,写时要想清楚。有两类无解情况:1.一段区间内元素值全相同,无法吃;2.无法分完,没有完全匹配。
以下为部分代码:
int now=1,nowsum=0,nowmaxx=0,maxxid,pd=a[1],o=1;
//now记录当前分到了哪一段 nowsum记录当前段中元素和
//nowmaxx记录当前段中区间最值 maxxid记录区间最值位置
//pd表示段中第一个元素 o记录是否区间内数都相同
for(int i=1;i<=n;i++){
if(nowsum>b[now]){
puts("NO");return 0;
}
nowsum+=a[i];
if(a[i]>nowmaxx){
nowmaxx=a[i];
maxxid=i;
}
if(a[i]!=pd)o=0;
if(nowsum==b[now]){
ans[now].id=i;
ans[now].maxx=maxxid;
if(o==1&&(i-ans[now-1].id)!=1){
puts("NO");
return 0;
}
now++;
nowsum=0;
nowmaxx=0;
pd=a[i+1];
o=1;
}
}
if(now!=m+1){
puts("NO");
return 0;
}
else{
puts("YES");
}
3.输出
注意判断情况,输出时注意判断位置已经改变。因为最大值只记录第一位,所以可以将一段中左边先全吃了。 可有一种特殊情况,如:
4
2 2 2 1
1
7
此时左边没有的吃,右边又吃不了,我们就得将最大值一步步往右移后将右边全吃了后在吃完左边。
以下为部分代码:
for(int i=1;i<=m;i++){
int flag=0;
int nm=ans[i].maxx-ans[i-1].id;
for(int j=ans[i].maxx;j>ans[i-1].id+1;j--){
printf("%d L\n",i-1+j-ans[i-1].id);
}
while(a[ans[i].maxx+1]==a[ans[i-1].id+1]&&a[ans[i].maxx+1]==a[ans[i].maxx]&&(ans[i].maxx+1)<=ans[i].id){
flag=1;
ans[i].maxx++;
}
if(flag==1){
for(int j=ans[i].maxx;j<ans[i].id;j++){
printf("%d R\n",ans[i].maxx-ans[i-1].id+i-1);
}
for(int j=ans[i].maxx;j>ans[i-1].id+1;j--){
printf("%d L\n",i-1+j-ans[i-1].id);
}
}
else{
for(int j=ans[i].maxx+1;j<=ans[i].id;j++){
printf("%d R\n",i);
}
}
}
完结。