模拟 [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 }
带注释的:
#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(); }