记录编号 458718 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [SDOI 2010] 猪国杀 最终得分 100
用户昵称 GravatarHzoi_Ivan 是否通过 通过
代码语言 C++ 运行时间 0.021 s
提交时间 2017-10-11 19:29:43 内存使用 1.11 MiB
显示代码纯文本
  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. #include<cmath>
  6. using namespace std;
  7. int n,m;
  8. char pai[2505][5];
  9. char pp[25]={'K','D','P','F','N','W','J','Z'};
  10. int pai_top;
  11. void die(int,int);
  12. struct pig{
  13. int blood;int id; //0主 1忠 2反 3跳忠 4跳反
  14. int lfp;//类反猪
  15. int zb;//装备
  16. int hp[2050];//0杀 1闪 2桃 3决斗 4南蛮 5万箭 6无懈 7弩
  17. int first,last;//最后一张手牌编号
  18. int pre[2050],nxt[2050],tmp[2050],num;
  19. pig(){
  20. blood=4;id=num=zb=lfp=last=first=0;
  21. memset(hp,0,sizeof hp);
  22. memset(pre,0,sizeof pre);
  23. memset(nxt,0,sizeof nxt);
  24. memset(tmp,0,sizeof tmp);
  25. }
  26. void in_id(){
  27. char ch[5]; scanf("%s",ch);
  28. if(ch[0]=='M')id=0;
  29. else if(ch[0]=='Z')id=1;
  30. else id=2;
  31. }
  32. void del(int x){
  33. nxt[pre[x]]=nxt[x];pre[nxt[x]]=pre[x];
  34. if(x==last)last=pre[x];
  35. if(x==first)first=nxt[x];
  36. }
  37. bool find(int x){
  38. for(int i=first;i;i=nxt[i])
  39. if(hp[i]==x){del(i);return 1;}
  40. return 0;
  41. }
  42. void hurt(int x,int y){
  43. blood--;
  44. if(blood==0){
  45. if(!find(2))::die(x,y);
  46. else blood++;
  47. }
  48. }
  49. void change(int x){
  50. if(x==1){
  51. if(id==1)id=3;
  52. if(id==2)id=4;
  53. lfp=0;
  54. }
  55. else lfp=1;
  56. }
  57. void take(char *ch){
  58. if(!ch[0])ch[0]=pai[m][0];
  59. if(ch[0]=='K')hp[++num]=0;
  60. if(ch[0]=='D')hp[++num]=1;
  61. if(ch[0]=='P')hp[++num]=2;
  62. if(ch[0]=='F')hp[++num]=3;
  63. if(ch[0]=='N')hp[++num]=4;
  64. if(ch[0]=='W')hp[++num]=5;
  65. if(ch[0]=='J')hp[++num]=6;
  66. if(ch[0]=='Z')hp[++num]=7;
  67. if(last==0)first=num;
  68. pre[num]=last;nxt[last]=num;
  69. nxt[num]=0;pre[0]=num;last=num;
  70. }
  71. }p[25];
  72. int pre[25],nxt[25],used_kill;
  73. void print(){
  74. for(int i=1;i<=n;i++){
  75. if(p[i].blood==0){printf("DEAD\n");}
  76. else{
  77. bool bo=0;
  78. for(int j=p[i].first;j;j=p[i].nxt[j]){
  79. if(bo){printf(" ");}
  80. bo=1;
  81. if(p[i].hp[j]==0){printf("K");}
  82. if(p[i].hp[j]==1){printf("D");}
  83. if(p[i].hp[j]==2){printf("P");}
  84. if(p[i].hp[j]==3){printf("F");}
  85. if(p[i].hp[j]==4){printf("N");}
  86. if(p[i].hp[j]==5){printf("W");}
  87. if(p[i].hp[j]==6){printf("J");}
  88. if(p[i].hp[j]==7){printf("Z");}
  89. }
  90. printf("\n");
  91. }
  92. }
  93. }
  94. bool check(){
  95. bool b0=0,b2=0;
  96. for(int i=1;i<=n;i++){
  97. if(p[i].blood>0){
  98. if(p[i].id==0)b0=1;
  99. if(p[i].id==2||p[i].id==4)b2=1;
  100. }
  101. }
  102. if(b0==1&&b2==1)return 0;
  103. else if(b0==0)printf("FP\n");
  104. else printf("MP\n");
  105. return 1;
  106. }
  107. void die(int x,int y){
  108. nxt[pre[y]]=nxt[y];
  109. pre[nxt[y]]=pre[y];
  110. if(check()){print();exit(0);}
  111. if(p[y].id==2||p[y].id==4)
  112. {p[x].take(pai[++pai_top]);p[x].take(pai[++pai_top]);p[x].take(pai[++pai_top]);}
  113. if(p[x].id==0&&(p[y].id==1||p[y].id==3)){
  114. memset(p[x].hp,0,sizeof p[x].hp);
  115. memset(p[x].pre,0,sizeof p[x].pre);
  116. memset(p[x].nxt,0,sizeof p[x].nxt);
  117. memset(p[x].tmp,0,sizeof p[x].tmp);
  118. p[x].zb=0; p[x].first=p[x].last=0;
  119. }
  120. }
  121. bool hate_check(int x,int y){
  122. if(p[x].id==0&&(p[y].id==4||p[y].lfp==1))return 1;
  123. if((p[x].id==1||p[x].id==3)&&p[y].id==4)return 1;
  124. if((p[x].id==2||p[x].id==4)&&(p[y].id==0||p[y].id==3))return 1;
  125. return 0;
  126. }
  127. bool love_check(int x,int y){
  128. if(p[x].id==0&&(p[y].id==3||p[y].id==0))return 1;
  129. if((p[x].id==1||p[x].id==3)&&(p[y].id==3||p[y].id==0))return 1;
  130. if((p[x].id==2||p[x].id==4)&&p[y].id==4)return 1;
  131. return 0;
  132. }
  133. bool make_hate(int be,int x){
  134. for(int i=be,bo=0;(bo!=1||i!=be);i=nxt[i]){
  135. bo=1;
  136. if(hate_check(i,x))
  137. if(p[i].find(6)){
  138. p[i].change(1);
  139. if(!make_hate(i,i))return 1;
  140. }
  141. }
  142. return 0;
  143. }
  144. bool make_love(int be,int x){
  145. for(int i=be,bo=0;(bo!=1||i!=be);i=nxt[i]){
  146. bo=1;
  147. if(love_check(i,x))
  148. if(p[i].find(6)){
  149. p[i].change(1);
  150. if(!make_hate(i,i))return 1;
  151. }
  152. }
  153. return 0;
  154. }
  155. void kill(int x,int y)
  156. {if(!p[y].find(1)){p[y].hurt(x,y);}}
  157. void fight(int x,int y){
  158. if(p[x].id==0&&(p[y].id==1||p[y].id==3)){
  159. p[y].hurt(x,y);
  160. return ;
  161. }
  162. if(make_love(x,y))return ;
  163. int now=y,de=x^y;
  164. while(p[now].find(0))now^=de;
  165. p[now].hurt(now^de,now);
  166. }
  167. void aoe(int x,int y){
  168. for(int i=nxt[x];i!=x;i=nxt[i]){
  169. if(make_love(x,i))continue;
  170. if(!p[i].find(y)){
  171. p[i].hurt(x,i);
  172. if(p[i].id==0&&(p[x].id==1||p[x].id==2)){p[x].change(0);}
  173. }
  174. }
  175. }
  176. bool check(int now,int x){//0杀 1闪 2桃 3决斗 4南蛮 5万箭 6无懈 7弩 8装备区
  177. if(p[now].hp[x]==0){
  178. if(hate_check(now,nxt[now])&&(used_kill==0||p[now].zb==1)){
  179. p[now].del(x);p[now].change(1);
  180. kill(now,nxt[now]); used_kill=1;
  181. return 1;
  182. }
  183. else return 0;
  184. }
  185. if(p[now].hp[x]==1){return 0;}
  186. if(p[now].hp[x]==2){
  187. if(p[now].blood<4){p[now].del(x);p[now].blood++;return 1;}
  188. else return 0;
  189. }
  190. if(p[now].hp[x]==3){
  191. if(hate_check(now,1)){
  192. p[now].del(x);p[now].change(1);
  193. fight(now,1);
  194. return 1;
  195. }
  196. for(int i=nxt[now];i!=now;i=nxt[i]){
  197. if(hate_check(now,i)){
  198. p[now].del(x);p[now].change(1);
  199. fight(now,i);
  200. return 1;
  201. }
  202. }
  203. return 0;
  204. }
  205. if(p[now].hp[x]==4){p[now].del(x);aoe(now,0);return 1;}
  206. if(p[now].hp[x]==5){p[now].del(x);aoe(now,1);return 1;}
  207. if(p[now].hp[x]==6){return 0;}
  208. if(p[now].hp[x]==7){p[now].del(x);p[now].zb=1;return 1;}
  209. return 0;
  210. }
  211. int work(int now){
  212. int x=p[now].nxt[0];
  213. while(x&&!check(now,x))x=p[now].nxt[x];
  214. return x;
  215. }
  216. int main(){
  217. freopen("kopk.in","r",stdin);
  218. freopen("kopk.out","w",stdout);
  219. scanf("%d%d",&n,&m);
  220. for(int i=1;i<=n;i++)pre[i]=i-1,nxt[i]=i+1;
  221. pre[1]=n;nxt[n]=1;
  222. for(int i=1;i<=n;i++){
  223. p[i].in_id();
  224. char ch[2];
  225. scanf("%s",ch);p[i].take(ch);
  226. scanf("%s",ch);p[i].take(ch);
  227. scanf("%s",ch);p[i].take(ch);
  228. scanf("%s",ch);p[i].take(ch);
  229. }
  230. for(int i=1;i<=m;i++)scanf("%s",pai[i]);
  231. int now=1;
  232. int tim=0;
  233. while(1){
  234. tim++;
  235. used_kill=0;
  236. p[now].take(pai[++pai_top]);p[now].take(pai[++pai_top]);
  237. while(p[now].blood>0&&work(now));
  238. now=nxt[now];
  239. if(pai_top>m)pai_top=m;
  240. }
  241. return 0;
  242. }