『Fwb』狼人の杀戮

· · 题解

更新

  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;
    }