题解 [SDOI2010]猪国杀

代码成功卡到600行以内

曾经发誓一天切掉的我打了两周。。。

先看题

要点还是挺多的,即使是像我这样熟悉三国杀的同(wán)学(jiā),也要认真看。


首先是基本牌的部分。

杀:在自己的回合内,对攻击范围内除自己以外的一名角色使用。如果没有被『闪』抵消,则造成1点伤害。无论有无武器,杀的攻击范围都是1;

直接看看自己的下家跳没跳,跳了的话就看看是不是一伙然后一刀砍下去,没跳直接return

注意,用了杀之后自己的身份就完全暴露了。


闪:当你受到杀的攻击时,可以弃置一张闪来抵消杀的效果;

这个没什么需要解释的吧,直接暴力看看有没有闪就行了。


桃:在自己的回合内,如果自己的体力值不等于体力上限,那么使用一个桃可以为自己补充一点体力,否则不能使用桃;桃只能对自己使用;在自己的回合外,如果自己的血变为0或者更低,那么也可以使用;

注意:不能对别人使用!!!


猪哥连弩:武器,攻击范围1,出牌阶段你可以使用任意张杀;

注意:即使之前有了也要再装一遍,把之前的顶掉(不愧是猪)。


看上去很简单,但是细节很多。

首先就是装上猪哥连弩之后前面的杀也是可以用的,需要i=0重新扫一遍。

还有题目描述中说保证牌数够用,不要相信它,牌堆没了就一直摸最后一张牌。

一个回合只能用一次杀(除非装了猪哥连弩)。


好了现在10分到手了。

接下来我们看锦囊牌。

决斗:出牌阶段,对除自己以外任意一名角色使用,由目标角色先开始,自己和目标角色轮流弃置一张杀,首先没有杀可弃的一方受到1点伤害,另一方视为此伤害的来源;

这个就一个while就暴力判断一下有没有杀就完事了,需要注意的是忠臣接收到主公的杀要直接掉血。

还有伤害来源不是用牌者而是对方。

要判断是跳反还是跳忠。


南猪入侵:出牌阶段,对除你以外所有角色使用,按逆时针顺序从使用者下家开始依次结算,除非弃置一张杀,否则受到1点伤害;

这里判断一下死了就直接跳过,蒟蒻因为这个调了好几天。。。

每个人都要判断。


万箭齐发:和南猪入侵类似,不过要弃置的不是杀而是闪;

做法和题上说的也一样,把杀换成闪就完事了。


还是很麻烦的,最后提醒一下按理来说除了桃使用任意一张手牌后都要重新扫一遍,比如说万箭齐发杀死了你的下家,然后前面的杀有可能就有了目标。

好的现在我们拿到30分了。


最后一个最恶心的部分——无懈可击。

orz一下各路用奇偶性来判断的神仙。

蒟蒻只会递归。。。

那么明确一下,无懈可击后,自己和对方的身份都已经暴露了。

判断一下受攻击的人跳没跳身份,如果没跳就直接return

记录一个flag判断是在献殷勤还是表敌意。

然后暴力枚举判断就行了,找到之后下一层递归要flag^=1

至此,猪国杀成功AC


上代码

Copy
#define N 2001001 #define MAX 2001 #define re register #define inf 1e18 #define eps 1e-10 using namespace std; typedef long long ll; typedef double db; inline void read(re ll &ret) { ret=0;re char c=getchar();re bool pd=false; while(!isdigit(c)){pd|=c=='-';c=getchar();} while(isdigit(c)){ret=(ret<<1)+(ret<<3)+(c&15);c=getchar();} ret=pd?-ret:ret; return; } ll n,m; struct zhu { ll paishu,leixing,xueliang;//leixing=1为主猪,2为忠猪,3为反猪 char pai[1000001]; bool zhuge,si,tiaozhong,tiaofan,leifan; }a[11]; char s[N]; char paidui[2001]; ll head; inline void print() { for(re int i=1;i<=n;i++) { if(a[i].si) printf("DEAD\n"); else { // cout<<i<<" "<<a[i].xueliang<<endl; for(re int j=1;j<=a[i].paishu;j++) { if(j>1) putchar(' '); putchar(a[i].pai[j]); } putchar('\n'); } } return; } inline void init() { read(n); read(m); for(re int i=1;i<=n;i++) { a[i].si=false; a[i].xueliang=4; a[i].zhuge=false; scanf("%s",s+1); if(s[1]=='M') a[i].leixing=1; else if(s[1]=='Z') a[i].leixing=2; else a[i].leixing=3; for(re int j=1;j<=4;j++) { scanf("%s",s+1); a[i].pai[++a[i].paishu]=s[1]; } } for(re int i=1;i<=m;i++) { scanf("%s",s+1); paidui[i]=s[1]; } } inline void yongpai(re ll num,re ll pos) { for(re int i=pos+1;i<=a[num].paishu;i++) a[num].pai[i-1]=a[num].pai[i]; a[num].paishu--; return; } inline void jieshu() { re bool mp=true,fp=true; for(re int i=1;i<=n;i++) { if(a[i].xueliang!=0&&a[i].leixing==3) mp=false; if(a[i].xueliang!=0&&a[i].leixing==1) fp=false; } if(mp) { printf("MP\n"); print(); exit(0); } if(fp) { printf("FP\n"); print(); exit(0); } return; } inline void mopai(re ll pos,re ll num) { for(re int i=1;i<=num;i++) { if(++head>m) head=m; a[pos].pai[++a[pos].paishu]=paidui[head]; } return; } inline void si(re ll num,re ll laiyuan) { // cout<<num<<" "<<laiyuan<<endl; if(a[num].xueliang>=1) return; for(re int i=1;i<=a[num].paishu;i++) { if(a[num].pai[i]=='P') { yongpai(num,i); a[num].xueliang++; break; } } if(a[num].xueliang<1) { a[num].si=true; jieshu(); if(a[num].leixing==3) mopai(laiyuan,3); else if(a[num].leixing==2&&a[laiyuan].leixing==1) { a[laiyuan].paishu=0; a[laiyuan].zhuge=false; } } return; } inline bool shan(re ll pos) { for(re int i=1;i<=a[pos].paishu;i++) { if(a[pos].pai[i]=='D') { yongpai(pos,i); return true; } } return false; } inline bool sha(re ll pos,re ll num) { for(re int i=pos+1;i<=n;i++) { if(a[i].si)continue; if((a[pos].leixing==1&&(a[i].tiaofan||a[i].leifan))||(a[pos].leixing==2&&a[i].tiaofan)||(a[pos].leixing==3&&(a[i].leixing==1||a[i].tiaozhong))) { yongpai(pos,num); if(a[i].tiaofan) { a[pos].tiaozhong=true; a[pos].leifan=false; } else if(a[i].tiaozhong||a[i].leixing==1) a[pos].tiaofan=true; if(!shan(i)) { a[i].xueliang--; si(i,pos); } return true; } return false; } for(re int i=1;i<pos;i++) { if(a[i].si)continue; if((a[pos].leixing==1&&(a[i].tiaofan||a[i].leifan))||(a[pos].leixing==2&&a[i].tiaofan)||(a[pos].leixing==3&&(a[i].leixing==1||a[i].tiaozhong))) { yongpai(pos,num); if(a[i].tiaofan) { a[pos].tiaozhong=true; a[pos].leifan=false; } else if(a[i].tiaozhong||a[i].leixing==1) a[pos].tiaofan=true; if(!shan(i)) { a[i].xueliang--; si(i,pos); } return true; } return false; } } inline bool wuxie(re ll pos,re ll to,re bool pd) { if(!a[to].tiaofan&&!a[to].tiaozhong&&a[to].leixing!=1)return false; if(pd) { re bool flag=false; for(re int i=pos;i<=n;i++) { if(a[i].si)continue; if((a[to].leixing==1&&(a[i].leixing==3))||(a[to].tiaozhong&&(a[i].leixing==3))||(a[to].tiaofan&&(a[i].leixing==1||a[i].leixing==2))) continue; for(re int j=1;j<=a[i].paishu;j++) { if(a[i].pai[j]=='J') { yongpai(i,j); if(a[to].leixing==1) { a[i].tiaozhong=true; a[i].leifan=false; } else if(a[to].leixing==2) { a[i].tiaozhong=true; a[i].leifan=false; } else { a[i].tiaofan=true; a[i].leifan=false; } // if((a[i].leixing==1&&a[pos].leixing==2)||(a[i].leixing==2&&(a[pos].leixing==1||a[pos].leixing==2))||(a[i].leixing==3&&a[pos].leixing==3)) return !wuxie(i,to,false); // else // return !wuxie(i,to,true); } } } for(re int i=1;i<pos;i++) { if(a[i].si)continue; if((a[to].leixing==1&&(a[i].leixing==3))||(a[to].tiaozhong&&(a[i].leixing==3))||(a[to].tiaofan&&(a[i].leixing==1||a[i].leixing==2))) continue; for(re int j=1;j<=a[i].paishu;j++) { if(a[i].pai[j]=='J') { yongpai(i,j); if(a[to].leixing==1) { a[i].tiaozhong=true; a[i].leifan=false; } else if(a[to].leixing==2) { a[i].tiaozhong=true; a[i].leifan=false; } else { a[i].tiaofan=true; a[i].leifan=false; } // if((a[i].leixing==1&&a[pos].leixing==2)||(a[i].leixing==2&&(a[pos].leixing==1||a[pos].leixing==2))||(a[i].leixing==3&&a[pos].leixing==3)) return !wuxie(i,to,false); // else // return !wuxie(i,to,true); } } } return false; } else { re bool flag=false; for(re int i=pos;i<=n;i++) { if(a[i].si)continue; if(!((a[to].leixing==1&&(a[i].leixing==3))||(a[to].tiaozhong&&(a[i].leixing==3))||(a[to].tiaofan&&(a[i].leixing==1||a[i].leixing==2)))) continue; for(re int j=1;j<=a[i].paishu;j++) { if(a[i].pai[j]=='J') { yongpai(i,j); if(a[to].leixing==1) { a[i].tiaofan=true; a[i].leifan=false; } else if(a[to].leixing==2) { a[i].tiaofan=true; a[i].leifan=false; } else { a[i].tiaozhong=true; a[i].leifan=false; } return !wuxie(i,to,true); } } } for(re int i=1;i<pos;i++) { if(a[i].si)continue; if(!((a[to].leixing==1&&(a[i].leixing==3))||(a[to].tiaozhong&&(a[i].leixing==3))||(a[to].tiaofan&&(a[i].leixing==1||a[i].leixing==2)))) continue; for(re int j=1;j<=a[i].paishu;j++) { if(a[i].pai[j]=='J') { yongpai(i,j); if(a[to].leixing==1) { a[i].tiaofan=true; a[i].leifan=false; } else if(a[to].leixing==2) { a[i].tiaofan=true; a[i].leifan=false; } else { a[i].tiaozhong=true; a[i].leifan=false; } return !wuxie(i,to,true); } } } return false; } } inline bool juedou(re ll pos,re ll num) { for(re int i=pos+1;i<=n;i++) { if(a[i].si)continue; if((a[pos].leixing==1&&(a[i].tiaofan||a[i].leifan))||(a[pos].leixing==2&&a[i].tiaofan)||(a[pos].leixing==3&&a[i].leixing==1)) { yongpai(pos,num); if(a[i].leixing==3) { a[pos].tiaozhong=true; a[pos].leifan=false; } else if(a[i].tiaozhong||a[i].leixing==1) a[pos].tiaofan=true; if(wuxie(pos,i,true)) return true; if(a[pos].leixing==1&&a[i].leixing==2) { a[i].xueliang--; si(i,pos); return true; } re ll turn=i; while(true) { re bool flag=false; for(re int j=1;j<=a[turn].paishu;j++) { if(a[turn].pai[j]=='K') { yongpai(turn,j); flag=true; break; } } if(!flag) { a[turn].xueliang--; si(turn,turn==pos?i:pos); return true; } if(turn==i) turn=pos; else turn=i; } } } for(re int i=1;i<pos;i++) { if(a[i].si)continue; if((a[pos].leixing==1&&(a[i].tiaofan||a[i].leifan))||(a[pos].leixing==2&&a[i].tiaofan)||(a[pos].leixing==3&&a[i].leixing==1)) { yongpai(pos,num); if(a[i].leixing==3) { a[pos].tiaozhong=true; a[pos].leifan=false; } else if(a[i].tiaozhong||a[i].leixing==1) a[pos].tiaofan=true; if(wuxie(pos,i,true)) return true; if(a[pos].leixing==1&&a[i].leixing==2) { a[i].xueliang--; si(i,pos); return true; } re ll turn=i; while(true) { re bool flag=false; for(re int j=1;j<=a[turn].paishu;j++) { if(a[turn].pai[j]=='K') { yongpai(turn,j); flag=true; break; } } if(!flag) { a[turn].xueliang--; si(turn,turn==pos?i:pos); return true; } if(turn==i) turn=pos; else turn=i; } } } return false; } inline void nanman(re ll pos,re ll num) { // cout<<pos<<" "<<num<<endl; yongpai(pos,num); for(re int i=pos+1;i<=n;i++) { if(a[i].si)continue; if(wuxie(pos,i,true))continue; re bool flag=false; for(re int j=1;j<=a[i].paishu;j++) { if(a[i].pai[j]=='K') { yongpai(i,j); flag=true; break; } } if(!flag) { a[i].xueliang--; if(a[i].leixing==1&&!a[pos].tiaozhong&&!a[pos].tiaofan) a[pos].leifan=true; si(i,pos); } } for(re int i=1;i<pos;i++) { if(a[i].si)continue; if(wuxie(pos,i,true))continue; re bool flag=false; for(re int j=1;j<=a[i].paishu;j++) { if(a[i].pai[j]=='K') { yongpai(i,j); flag=true; break; } } if(!flag) { a[i].xueliang--; if(a[i].leixing==1&&!a[pos].tiaozhong&&!a[pos].tiaofan) a[pos].leifan=true; si(i,pos); } } return; } inline void wanjian(re ll pos,re ll num) { // cout<<pos<<" "<<num<<endl; yongpai(pos,num); for(re int i=pos+1;i<=n;i++) { if(a[i].si)continue; if(wuxie(pos,i,true))continue; if(!shan(i)) { a[i].xueliang--; if(a[i].leixing==1&&!a[pos].tiaozhong&&!a[pos].tiaofan) a[pos].leifan=true; si(i,pos); } } for(re int i=1;i<pos;i++) { if(a[i].si)continue; if(wuxie(pos,i,true))continue; if(!shan(i)) { a[i].xueliang--; if(a[i].leixing==1&&!a[pos].tiaozhong&&!a[pos].tiaofan) a[pos].leifan=true; si(i,pos); } } return; } inline void chupai(re ll pos) { re bool chuguosha=false; for(re int i=1;i<=a[pos].paishu;i++) { if(a[pos].si) return; if(a[pos].pai[i]=='P') { if(a[pos].xueliang<4) { yongpai(pos,i); i=0; a[pos].xueliang++; } } else if(a[pos].pai[i]=='K'&&(!chuguosha||a[pos].zhuge)) { if(sha(pos,i)) { i=0; chuguosha=true; } } else if(a[pos].pai[i]=='F') { if(juedou(pos,i)) i=0; } else if(a[pos].pai[i]=='N') { nanman(pos,i); i=0; } else if(a[pos].pai[i]=='W') { wanjian(pos,i); i=0; } else if(a[pos].pai[i]=='Z') { a[pos].zhuge=true; yongpai(pos,i); i=0; } // cout<<i<<endl; } return; } /* 『桃(P)』 『杀(K)』 『闪(D)』 『决斗(F)』 『南猪入侵(N)』 『万箭齐发(W)』 『无懈可击(J)』 『猪哥连弩(Z)』 */ inline void work() { re ll num=0; while(true) { num%=n; num++; if(a[num].si) continue; mopai(num,2); chupai(num); } } signed main() { init(); work(); exit(0); } //[SDOI2010]猪国杀
posted @   CelticOIer  阅读(245)  评论(1编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示