模拟 [Sdoi2010]猪国杀

题目的可读版本

有那么几个地方需要注意:
1.使用一个锦囊后,先判无懈可击。
2.如果一个猪出完一个牌后,要从头开始看哪个能出(有可能一次出牌后某只猪跳忠或者跳反了,F,K什么的就可以用了。)
3.游戏结束时,没抓的牌就不用抓了。
4.循环无懈可击
5.行末没空格

昨天打的时候,有个没玩过三国杀的dalao问我能不能无懈杀。。。。
其实这种题完全没有思维含量,只要打之前把所有细节构思好,之后开始码,不要把变量定义混乱,调之前写好注释。。。也就没啥了,一定要有耐心。我也就调了10h左右。。。。
4.9k的代码貌似已经算很短的了。我分别提供带注释和不带注释的代码
其实带注释的代码看起来就像你真的在玩一样,反正都是模拟。。
无注释的

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <algorithm>
  6 #define ll long long
  7 using namespace std;
  8 int n,m,cnt,sum,nex[15],fro[15];//cnt表示使用到第几张牌,sum表示剩余FP数量
  9 int head[15],tail[15],dead[15],out[15][2005],blood[15],jump[15],nu[15];//jump:1->ZP,2->FP,3->L_AP
 10 char card[2005][2],pig[15][3],hand[15][2005][2];
 11 bool P(int x)
 12 {
 13     if(blood[x]!=4){blood[x]++;return 1;}
 14     return 0;
 15 }
 16 bool get_D(int x)
 17 {
 18     for(int i=head[x];i<=tail[x];i++)
 19         if(!out[x][i]&&hand[x][i][0]=='D'){out[x][i]=1;return 1;}
 20     return 0;
 21 }
 22 bool get_J(int x)
 23 {
 24     for(int i=head[x];i<=tail[x];i++)
 25         if(!out[x][i]&&hand[x][i][0]=='J'){out[x][i]=1;return 1;}
 26     return 0;
 27 }
 28 bool get_K(int x)
 29 {
 30     for(int i=head[x];i<=tail[x];i++)
 31         if(!out[x][i]&&hand[x][i][0]=='K'){out[x][i]=1;return 1;}
 32     return 0;
 33 }
 34 void dying(int x,int y)//x为进攻者,y为死者
 35 {
 36     for(int i=head[y];i<=tail[y];i++)
 37         if(!out[y][i]&&hand[y][i][0]=='P')
 38         {
 39             out[y][i]=1;blood[y]=1;return;
 40         }
 41     dead[y]=1;nex[fro[y]]=nex[y];fro[nex[y]]=fro[y];
 42     if(pig[y][0]=='F')sum--;    
 43     if(sum==0||blood[1]<=0)return;
 44     if(pig[y][0]=='F')
 45     {
 46         cnt++;if(cnt>m)cnt=m;hand[x][++tail[x]][0]=card[cnt][0];
 47         cnt++;if(cnt>m)cnt=m;hand[x][++tail[x]][0]=card[cnt][0];
 48         cnt++;if(cnt>m)cnt=m;hand[x][++tail[x]][0]=card[cnt][0];
 49         return;
 50     }
 51     if(pig[y][0]=='Z'&&x==1)
 52     {
 53         nu[x]=0;
 54         for(int i=head[x];i<=tail[x];i++)out[x][i]=1;
 55         head[x]=tail[x]+1;
 56         return;
 57     }   
 58 }
 59 bool K(int x)
 60 {
 61     int y=nex[x];
 62     if((jump[y]==1&&pig[x][0]=='F')||(pig[x][0]=='M'&&(jump[y]==2||jump[y]==3))||(pig[x][0]=='Z'&&jump[y]==2))
 63     {
 64         if(get_D(y)==0){blood[y]--;if(blood[y]<=0)dying(x,y);}
 65         if(pig[x][0]=='Z')jump[x]=1;
 66         if(pig[x][0]=='F')jump[x]=2;
 67         return 1;
 68     }
 69     return 0;
 70 }
 71 bool J(int star,int x,int ch)
 72 {
 73     if(!jump[x]||jump[x]==3)return ch;int y,p=0;
 74     for(int i=star;;i=nex[i])
 75     {
 76         y=i;if(p&&y==star)break;p=1;
 77         if(ch==1)
 78         {
 79             if(jump[x]==1&&(pig[y][0]=='Z'||pig[y][0]=='M'))
 80                 if(get_J(y))
 81                 {
 82                     ch=0,jump[y]=1;
 83                     return J(y,x,ch);
 84                 }
 85             if(jump[x]==2&&pig[y][0]=='F')
 86                 if(get_J(y))
 87                 {
 88                     ch=0,jump[y]=2;
 89                     return J(y,x,ch);
 90                 }
 91         }
 92         else
 93         {
 94             if(jump[x]==1&&pig[y][0]=='F')
 95                 if(get_J(y))
 96                 {
 97                     ch=1,jump[y]=2;
 98                     return J(y,x,ch);
 99                 }
100             if(jump[x]==2&&(pig[y][0]=='Z'||pig[y][0]=='M'))
101                 if(get_J(y))
102                 {
103                     ch=1,jump[y]=1;
104                     return J(y,x,ch);
105                 }
106         }
107     }
108     return ch;
109 }
110 bool F(int x)
111 {
112     int y=0;
113     if(pig[x][0]=='F'){y=1;jump[x]=2;}
114     if(pig[x][0]=='Z')
115         for(int i=nex[x];;i=nex[i])
116         {
117             if(i==x)break;
118             if(jump[i]==2){y=i;jump[x]=1;break;}
119         }
120     if(pig[x][0]=='M')
121         for(int i=nex[x];;i=nex[i])
122         {
123             if(i==x)break;
124             if(jump[i]==2||jump[i]==3){y=i;break;}
125         }
126     if(!y)return 0;
127     int er=y;         
128     if(J(x,y,1)==0){return 1;}            
129     if(x==1&&pig[y][0]=='Z'){blood[y]--;if(blood[y]<=0)dying(x,y);return 1;}
130     while(1)
131     {
132         if(get_K(er)==0)
133         {
134             blood[er]--;
135             if(blood[er]<=0)dying(er==x?y:x,er);
136             break;
137         }
138         if(er==x)er=y;else er=x;
139     }
140     return 1;
141 }
142 void N(int x)
143 {
144     for(int i=nex[x];;i=nex[i])
145     {
146         int y=i;if(y==x)break; 
147         if(J(x,y,1)==0){continue;}  
148         if(get_K(y)==0)
149         {
150             blood[y]--;if(blood[y]<=0)dying(x,y);
151             if(!jump[x]&&y==1)jump[x]=3;
152             if(sum==0||dead[1]==1)return;
153         }
154     }
155     return;
156 }
157 void W(int x)
158 {
159     for(int i=nex[x];;i=nex[i])
160     {
161         int y=i;if(y==x)break;
162         if(J(x,y,1)==0){ continue;}
163         if(get_D(y)==0)
164         {
165             blood[y]--;if(blood[y]<=0)dying(x,y);
166             if(!jump[x]&&y==1)jump[x]=3;
167             if(sum==0||dead[1]==1)return;
168         }
169     }
170     return;
171 }
172 bool play()
173 {
174     int x=1;
175     while(1)
176     {
177         cnt++;if(cnt>m)cnt=m;hand[x][++tail[x]][0]=card[cnt][0];
178         cnt++;if(cnt>m)cnt=m;hand[x][++tail[x]][0]=card[cnt][0];
179         int kill=0;
180         for(int i=head[x];i<=tail[x];i++)
181         {
182             int use=0;
183             if(out[x][i])continue;string c=hand[x][i];
184             if(c[0]=='P')if(P(x)){out[x][i]=1;use=1;}
185             if(c[0]=='K'&&(!kill||nu[x]))if(K(x)){out[x][i]=1;kill=1;if(nu[x]==1)kill=0;use=1;}
186             if(c[0]=='D')continue;
187             if(c[0]=='F')if(F(x)){out[x][i]=1;use=1;}
188             if(c[0]=='N'){N(x);out[x][i]=1;use=1;}
189             if(c[0]=='W'){W(x);out[x][i]=1;use=1;}
190             if(c[0]=='J')continue;
191             if(c[0]=='Z'){nu[x]=1;out[x][i]=1;use=1;}
192             if(dead[x])break;
193             if(blood[1]==0)return 0;
194             if(sum==0)return 1;
195             if(use==1)i=head[x]-1;
196         }
197         while(out[x][head[x]]==1)head[x]++;
198         x=nex[x];
199     }
200 }
201 void init()
202 {
203     scanf("%d%d",&n,&m);
204     for(int i=1;i<=n;i++)
205     {
206         scanf("%s",pig[i]);if(pig[i][0]=='F')sum++;
207         for(int j=1;j<=4;j++)scanf("%s",hand[i][j]);tail[i]=4;head[i]=1;
208         fro[i]=i-1;nex[i]=i+1;blood[i]=4;
209     }
210     fro[1]=n;nex[n]=1;jump[1]=1;
211     for(int i=1;i<=m;i++)scanf("%s",card[i]);
212 }
213 void jieshu()
214 {
215     if(play())printf("MP\n");
216     else printf("FP\n");
217     for(int i=1;i<=n;i++)
218     {
219         if(dead[i]){printf("DEAD\n");continue;}
220         int sum=0;char hh[2005][3];
221         for(int j=head[i];j<=tail[i];j++)if(!out[i][j])hh[++sum][0]=hand[i][j][0];
222         for(int j=1;j<sum;j++)printf("%c ",hh[j][0]);
223         if(sum==0)printf("\n");
224         else printf("%c\n",hh[sum][0]);
225     }
226 }
227 int main()
228 {
229     init();
230     jieshu();
231 }
View Code

 

带注释的:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
int n,m,cnt,sum,nex[15],fro[15];//cnt表示使用到第几张牌,sum表示剩余FP数量
int head[15],tail[15],dead[15],out[15][2005],blood[15],jump[15],nu[15];//jump:1->ZP,2->FP,3->L_AP
char card[2005][2],pig[15][3],hand[15][2005][2];
bool P(int x)
{
    if(blood[x]!=4){printf("%d use a P\n",x);blood[x]++;return 1;}              
    return 0;
}
bool get_D(int x)
{
    for(int i=head[x];i<=tail[x];i++)
        if(!out[x][i]&&hand[x][i][0]=='D'){out[x][i]=1;return 1;}
    return 0;
}
bool get_J(int x)
{
    for(int i=head[x];i<=tail[x];i++)
        if(!out[x][i]&&hand[x][i][0]=='J'){out[x][i]=1;return 1;}
    return 0;
}
bool get_K(int x)
{
    for(int i=head[x];i<=tail[x];i++)
        if(!out[x][i]&&hand[x][i][0]=='K'){out[x][i]=1;return 1;}
    return 0;
}
void dying(int x,int y)//x为进攻者,y为死者
{
    for(int i=head[y];i<=tail[y];i++)
        if(!out[y][i]&&hand[y][i][0]=='P')
        {
            printf("%d use a P to save himself\n",y);
            out[y][i]=1;blood[y]=1;return;
        }
    dead[y]=1;nex[fro[y]]=nex[y];fro[nex[y]]=fro[y];    printf("%d dead,killed by %d\n",y,x);
    if(pig[y][0]=='F')sum--;                printf("how about FP:%d\n",sum);
    if(sum==0||blood[1]<=0)return;
    if(pig[y][0]=='F')
    {
        cnt++;if(cnt>m)cnt=m;hand[x][++tail[x]][0]=card[cnt][0];
        cnt++;if(cnt>m)cnt=m;hand[x][++tail[x]][0]=card[cnt][0];
        cnt++;if(cnt>m)cnt=m;hand[x][++tail[x]][0]=card[cnt][0];
        return;
    }
    if(pig[y][0]=='Z'&&x==1)
    {
        nu[x]=0;
        for(int i=head[x];i<=tail[x];i++)out[x][i]=1;
        head[x]=tail[x]+1;
        return;
    }    
}
bool K(int x)
{
    int y=nex[x];
    if((jump[y]==1&&pig[x][0]=='F')||(pig[x][0]=='M'&&(jump[y]==2||jump[y]==3))||(pig[x][0]=='Z'&&jump[y]==2))
    {
        printf("%d wants to kill %d\n",x,y);                                                       
        if(get_D(y)==0){blood[y]--;if(blood[y]<=0)dying(x,y);}printf("%d blood -1\n",y);
        if(pig[x][0]=='Z')jump[x]=1;
        if(pig[x][0]=='F')jump[x]=2;
        return 1;
    }
    return 0;
}
bool J(int star,int x,int ch)
{
    if(!jump[x]||jump[x]==3)return ch;int y,p=0;  printf("to whom %d and how about now %d\n",x,ch);   
    for(int i=star;;i=nex[i])
    {
        y=i;if(p&&y==star)break;p=1;
        if(ch==1)
        {
            if(jump[x]==1&&(pig[y][0]=='Z'||pig[y][0]=='M'))
                if(get_J(y))
                {
                    printf("%d give a J to %d\n",y,x);                     
                    ch=0,jump[y]=1;
                    return J(y,x,ch);
                }
            if(jump[x]==2&&pig[y][0]=='F')
                if(get_J(y))
                {
                    printf("%d give a J to %d\n",y,x);                  
                    ch=0,jump[y]=2;
                    return J(y,x,ch);
                }
        }
        else
        {
            if(jump[x]==1&&pig[y][0]=='F')
                if(get_J(y))
                {
                    printf("%d give a J to %d\n",y,x);                     
                    ch=1,jump[y]=2;
                    return J(y,x,ch);
                }
            if(jump[x]==2&&(pig[y][0]=='Z'||pig[y][0]=='M'))
                if(get_J(y))
                {
                    printf("%d give a J to %d\n",y,x);                     
                    ch=1,jump[y]=1;
                    return J(y,x,ch);
                }
        }
    }
    return ch;
}
bool F(int x)
{
    int y=0;
    if(pig[x][0]=='F'){y=1;jump[x]=2;}
    if(pig[x][0]=='Z')
        for(int i=nex[x];;i=nex[i])
        {
            if(i==x)break;
            if(jump[i]==2){y=i;jump[x]=1;break;}
        }
    if(pig[x][0]=='M')
        for(int i=nex[x];;i=nex[i])
        {
            if(i==x)break;
            if(jump[i]==2||jump[i]==3){y=i;break;}
        }
    if(!y)return 0;
    int er=y;printf("attarker %d and %d\n",x,y);                                  
    if(J(x,y,1)==0){return 1;}                      printf("J is used to %d\n",y);
    if(x==1&&pig[y][0]=='Z'){blood[y]--;if(blood[y]<=0)dying(x,y);return 1;}
    while(1)
    {
        printf("who %d\n",er);                                                    
        if(get_K(er)==0)
        {
            printf("loser %d\n",er);                                              
            blood[er]--;printf("%d blood -1\n",er);
            if(blood[er]<=0)dying(er==x?y:x,er);
            break;
        }
        if(er==x)er=y;else er=x;
    }
    return 1;
}
void N(int x)
{
    printf("Nan Zhu Run Qin; from %d\n",x);                            
    for(int i=nex[x];;i=nex[i])
    {
        int y=i;if(y==x)break; printf("to whom %d\n",y);              
        if(J(x,y,1)==0){continue;}     printf("J is used to %d\n",y);
        if(get_K(y)==0)
        {
            printf("%d blood -1\n",y);                                     
            blood[y]--;if(blood[y]<=0)dying(x,y);
            if(!jump[x]&&y==1)jump[x]=3;
            if(sum==0||dead[1]==1)return;
        }
    }
    return;
}
void W(int x)
{
    printf("Wan Jian Qi Fa; from %d\n",x);                            
    for(int i=nex[x];;i=nex[i])
    {
        int y=i;if(y==x)break;printf("to whom %d\n",y);              
        if(J(x,y,1)==0){ continue;}    printf("J is used to %d\n",y);
        if(get_D(y)==0)
        {
            printf("%d blood -1\n",y);                                       
            blood[y]--;if(blood[y]<=0)dying(x,y);
            if(!jump[x]&&y==1)jump[x]=3;
            if(sum==0||dead[1]==1)return;
        }
    }
    return;
}
bool play()
{
    int x=1;
    while(1)
    {
        cnt++;if(cnt>m)cnt=m;hand[x][++tail[x]][0]=card[cnt][0];
        cnt++;if(cnt>m)cnt=m;hand[x][++tail[x]][0]=card[cnt][0];
        int kill=0;
        printf("player%d\n",x);                                            
        for(int j=head[x];j<=tail[x];j++)                                  
                if(!out[x][j])printf("%s ",hand[x][j]); printf("\n");      
        for(int i=head[x];i<=tail[x];i++)
        {
            int use=0;
            if(out[x][i])continue;string c=hand[x][i];
            if(c[0]=='P')if(P(x)){out[x][i]=1;use=1;}
            if(c[0]=='K'&&(!kill||nu[x]))if(K(x)){out[x][i]=1;kill=1;if(nu[x]==1)kill=0;use=1;}
            if(c[0]=='F')if(F(x)){out[x][i]=1;use=1;}
            if(c[0]=='N'){N(x);out[x][i]=1;use=1;}
            if(c[0]=='W'){W(x);out[x][i]=1;use=1;}
            if(c[0]=='Z'){nu[x]=1;out[x][i]=1;use=1;}
            if(dead[x])break;
            if(blood[1]==0)return 0;
            if(sum==0)return 1;
            printf("%c\n",c[0]);
            for(int k=1;k<=n;k++)                                             
            {
                printf("pig%d %s jump%d blood%d    ",k,pig[k],jump[k],blood[k]);
                for(int j=head[k];j<=tail[k];j++)
                    if(!out[k][j])printf("%s ",hand[k][j]);
                printf("\n");
            }
            system("pause");
            if(use==1)i=head[x]-1,printf("%d will check again\n",x);
        }
        while(out[x][head[x]]==1)head[x]++;
        x=nex[x];
    }
}
void init()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",pig[i]);if(pig[i][0]=='F')sum++;
        for(int j=1;j<=4;j++)scanf("%s",hand[i][j]);tail[i]=4;head[i]=1;
        fro[i]=i-1;nex[i]=i+1;blood[i]=4;
    }
    fro[1]=n;nex[n]=1;jump[1]=1;
    for(int i=1;i<=m;i++)scanf("%s",card[i]);
}
void jieshu()
{
    if(play())printf("MP\n");
    else printf("FP\n");
    for(int i=1;i<=n;i++)
    {
        if(dead[i]){printf("DEAD\n");continue;}
        int sum=0;char hh[2005][3];
        for(int j=head[i];j<=tail[i];j++)if(!out[i][j])hh[++sum][0]=hand[i][j][0];
        for(int j=1;j<sum;j++)printf("%c ",hh[j][0]);
        if(sum==0)printf("\n");
        else printf("%c\n",hh[sum][0]);
    }
}
int main()
{
    init();//预处理
    jieshu();
}
View Code

 

posted @ 2017-10-09 21:25  Hzoi_QTY  阅读(149)  评论(0编辑  收藏  举报