『Fwb』狼人の杀戮
showtodo
·
·
题解
更新
-
-
### 思路
很显然,这是一道不简单的模拟。
以下提出几点个人认为需注意的点:
1. 可能有多个相同的身份。
2. 每个狼人都能且只能开一刀,与现实的狼人杀不同。
3. 女巫可以自救。
4. 猎人被救活可以不开枪。
5. 猎人没被救活则必须开枪。
6. 当晚有错误的操作后必须将当晚的所有操作都撤回。
7. 猎人被刀开枪后被复活又被刀可以再开枪。
8. 解药和毒药不可在同一晚使用,每个女巫只有两瓶不同的药。
### 代码
```
//我绝对不会告诉你们我交了7次题解
#include<cstdio>
const int N=25;
int t,n,m,op,id1,id2;
int a[N];//记录身份
int die[N];//记录此人是否死亡
int jy[N];//记录女巫是否有解药
int dy[N];//记录女巫是否有毒药
bool wr;//记录是否有错误操作
bool wf[N];//记录狼是否开刀
bool uy[N];//记录女巫是否用药
bool qs[N];//记录猎人是否开枪
int main(){
scanf("%d%d",&t,&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
//以下为模拟部分
for(int i=1;i<=t;i++){
wr=0;
for(int j=1;j<=n;j++){
uy[j]=qs[j]=wf[j]=0;//初始化
}
scanf("%d",&m);
while(m--){
scanf("%d%d%d",&op,&id1,&id2);
if(wr){continue;}
if(id1>n||id1<1){wr=1;continue;}
if(id2>n||id2<1){wr=1;continue;}
if(a[id1]==2){wr=1;continue;}//如果是平民
if(!op){//狼开刀
if(die[id1]||die[id2]){wr=1;continue;}//双方是否没了
if(a[id1]!=1){wr=1;continue;}//如果不是狼
if(id1==id2){wr=1;continue;}//如果为自刀
if(wf[id1]){wr=1;continue;}//如果已经开过刀
//以下为标记
wf[id1]=1;
die[id2]=i;//第i日死亡
qs[id2]=0;//切记不要像我一样把id1写成id2
continue;
}
if(op==1){//女巫毒人
if(die[id1]||die[id2]||id1==id2){wr=1;continue;}//如果是自毒或双方中有人没了
if(a[id1]!=4){wr=1;continue;}//如果不是女巫
if(dy[id1]){wr=1;continue;}//如果用过毒药了
if(uy[id1]){wr=1;continue;}//本轮用过药了
//以下为标记
uy[id1]=1;
dy[id1]=i;//第i日用毒药
die[id2]=i;
qs[id2]=0;
continue;
}
if(op==2){//女巫救人
if(a[id1]!=4){wr=1;continue;}//如果不是女巫
if(die[id1]&&id1!=id2){wr=1;continue;}//如果女巫没了且没自救
if(die[id2]!=i){wr=1;continue;}//如果人不是当晚没的
if(uy[id1]||jy[id1]){wr=1;continue;}//用过药或没解药
jy[id1]=i;//第i日用解药
//以下为标记
uy[id1]=1;
die[id2]=qs[id2]=0;
continue;
}
if(op==3){//猎人开枪
if(a[id1]!=3){wr=1;continue;}//不是猎人
if(qs[id1]){wr=1;continue;}//开过枪了
if(id1==id2){wr=1;continue;}//猎人枪自己
if(die[id1]!=i){wr=1;continue;}//猎人不是当晚没的
if(die[id2]){wr=1;continue;}//对方已经没了
//以下为标记
qs[id1]=1;
die[id2]=i;
continue;
}
wr=1;//如果op不为0,1,2,3
}
int tot=0;
for(int j=1;j<=n;j++){
if(die[j]==i){
tot++;
if(a[j]==3&&!qs[j]){//猎人没了且没开枪
wr=1;
break;
}
}
}
if(wr){//错了
for(int j=1;j<=n;j++){
//以下为撤回
if(die[j]==i) die[j]=0;
if(dy[j]==i) dy[j]=0;
if(jy[j]==i) jy[j]=0;
}
puts("Wrong");
continue;
}
if(!tot){puts("Safe");continue;}//平安夜
//以下为死人了的情况
printf("%d ",tot);
for(int j=1;j<=n;j++){
if(die[j]==i) printf("%d ",j);
}
putchar('\n');
}
return 0;
}
```