洛谷P2482 [SDOI2010]猪国杀——题解

猪国杀,模拟题的一颗耀眼的明珠,成长大牛、锻炼码力必写题!

模拟题没什么思维难度。只要按部就班地去做就是。模拟简单在这,难也在这。因为题面巨长,条件巨多,忽疏一点都有可能全盘皆输。故推荐考试时碰见了,除非真的闲的没事,否则尽量不要碰。一旦陷入细节混乱的深渊,估计一上午/下午的考试就混过去了。

总结一下做题的注意点:

  1、审题是最基本的!

     做大模拟题时,必须要认真读题,可能的话,要把所有条件都列举出来(不然就会像我一样,调了一上午才发现就是忘了几个题目中提到的条件或要求)。

  2、理清思路。

     不要吝啬草稿纸,把框架、注意点都写出来。相信我,除非您是AKIOI/NOI/CSP很强的大佬,否则在敲了几百行代码后,肯定会忘了些什么的。而忘了的,都会成为事后艰难调试的根源之一。
     同时,写代码时推荐多利用自定义函数,变量名尽量都用自己熟悉的、见名知意的。这样不仅使程序层次清晰、易于理解,还方便后期的调试(不然写了500行代码后再回来看a1,a2..什么的自己都不知道意义的变量,想死的心都有了)

  3、对于本题来说,找准对象、明确不同对象之间行为的差别也是很有必要的。这种细节特别容易忘,而找起来不留意的话也很难找。

 

接下来说一下我犯过的容易掉的坑吧,注意一下,这也算是这片题解的主体(没准您就掉进这些坑中呢?)

  1、杀死反猪后会摸牌,要注意猪能否再出牌

  2、 反猪决斗优先打主公(读题)

  3、决斗可能会自杀

  4、决斗只能在第一个人出杀前被无懈可击掉

  5、要注意用牌的顺序(从左到右),以便输出

  6、杀、决斗、无懈可击都会标明身份,南猪入侵和万箭齐发顶多在未表明身份时被主猪认为类反贼

  7、决斗时,主公认为对面是类反贼,实际上是忠臣的情况下,忠臣要牺牲一滴血(连无懈可击也不能出)

  8、当自己没表明身份时,不能对自己用无懈可击

  9、牌能用,要先把用牌的标记打上,免得主杀忠弃牌后再打标记导致错误

  10、装上猪哥连弩有可能使前面的杀能用

  11、中途有新的猪表明身份后,也有可能能让前面的决斗或杀能用。

  12、要每次都用最左边的能用的牌,是对全体来说,而不是对某种来说!

  13、“无懈可击:在目标锦囊生效前抵消其效果。每次有一张锦囊即将生效时,从使用这张锦囊的猪开始,按照逆时针顺序,依次得到使用无懈可击的机会”。这一点与三国杀不同,三国杀是从锦囊牌的对象开始的。但这里是猪国杀

  14、for循环后i会+1,如重新从左到右看牌,i不能取1,要取0。

  15、当牌堆没有牌时,会一直摸最后一张牌。(这就是RE点的原因吧)

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 
  5 using namespace std;
  6 
  7 const int N=15,M=2005;
  8 
  9 int n,m,win,top,fan,usesha,liangshengfen;
 10 
 11 char ch,pai;
 12 
 13 bool vis[N][M],allsf[N];
 14 
 15 struct PIG{
 16     int liv,rit,tot,iden,leifan,biao,zhuge,xie;
 17     int wuxie,sha,shan,tao;
 18     char card[M+4];
 19     int used[M+4];
 20 }pig[N];
 21 
 22 char Card[M],sf[10];
 23 
 24 inline char readch()
 25 {
 26     ch=getchar();
 27     while(ch<'A'||ch>'Z') 
 28         ch=getchar();
 29     return ch;
 30 }
 31 
 32 inline void init()
 33 {
 34     scanf("%d%d",&n,&m);
 35     for(int i=1;i<=n;++i)
 36     {
 37         pig[i].liv=1;pig[i].xie=4;
 38         scanf("%s",sf);
 39         switch(sf[0])
 40         {
 41             case 'M':pig[i].iden=3;pig[i].biao=1;break;
 42             case 'Z':pig[i].iden=1;break;
 43             default:
 44                 fan++;
 45         }
 46         for(int j=1;j<=4;++j)
 47         {
 48             pai=readch();
 49             switch(pai)
 50             {
 51                 case 'J':
 52                     pig[i].wuxie++;break;
 53                 case 'K':
 54                     pig[i].sha++;break;
 55                 case 'D':
 56                     pig[i].shan++;break;
 57                 case 'P':
 58                     pig[i].tao++;break;
 59                     
 60             }
 61             pig[i].tot++;
 62             pig[i].card[++pig[i].rit]=pai;
 63         }
 64             
 65     }
 66     for(int i=1;i<=m;++i)
 67         Card[i]=readch();
 68     top=1;
 69 }
 70 
 71 inline void yongtao(int u)
 72 {
 73     for(int i=1;i<=pig[u].rit;++i)
 74     if(!pig[u].used[i]&&pig[u].card[i]=='P')
 75     {
 76         pig[u].used[i]=1;
 77         return;
 78     }
 79 }
 80 
 81 inline void yonggewuxie(int u)
 82 {
 83     for(int i=1;i<=pig[u].rit;++i)
 84         if(!pig[u].used[i]&&pig[u].card[i]=='J')
 85         {
 86             pig[u].used[i]=1;
 87             return;
 88         }
 89 }
 90 
 91 inline void yongsha(int u,int ge)
 92 {
 93     if(!ge)
 94         return;
 95     for(int i=1;i<=pig[u].rit;++i)
 96         if(!pig[u].used[i]&&pig[u].card[i]=='K')
 97         {
 98             pig[u].used[i]=1;
 99             ge--;
100             if(!ge)
101                 return;
102         }
103 }
104 
105 inline void yongshan(int u)
106 {
107     for(int i=1;i<=pig[u].rit;++i)
108         if(!pig[u].used[i]&&pig[u].card[i]=='D')
109         {
110             pig[u].used[i]=1;
111             return;
112         }
113 }
114 
115 int yongwuxie(int u,int good,int sta)//表身份 
116 {
117     if(pig[u].biao==0) 
118     {
119         if(pig[u].leifan==1)
120         {
121             if(good) return 0;
122             if(pig[1].wuxie)
123             {
124                 pig[1].wuxie--;
125                 pig[1].tot--;
126                 yonggewuxie(1);
127                 if(!yongwuxie(1,0,1)) return 1;
128                 else return 0;
129             }
130         }
131         else 
132             return 0;
133     }
134     int k=n,now=sta-1;
135     if(good)
136     {
137         while(k--)
138         {
139             now++;
140             if(now>n) 
141                 now=1;
142             if(!pig[now].liv) continue;
143             if((pig[now].iden&1)==(pig[u].iden&1)&&pig[now].wuxie)
144             {
145                 pig[now].wuxie--;
146                 pig[now].tot--;
147                 yonggewuxie(now);
148                 if(pig[now].biao==0)
149                 pig[now].biao=1,liangshengfen=1;
150                 if(!yongwuxie(now,0,now)) return 1;
151                 else return 0;
152             }
153         }
154         return 0;
155     }
156     else
157     {
158         while(k--)
159         {
160             now++;
161             if(now>n) 
162                 now=1;
163             if(!pig[now].liv) continue;
164             if((pig[now].iden&1)!=(pig[u].iden&1)&&pig[now].wuxie)
165             {
166                 pig[now].wuxie--;
167                 pig[now].tot--;
168                 yonggewuxie(now);
169                 if(pig[now].biao==0)
170                 pig[now].biao=1,liangshengfen=1;
171                 if(!yongwuxie(now,0,now)) return 1;
172                 else return 0;
173             }
174         }
175         return 0;
176     }
177 }
178 
179 inline void mosanzhang(int u)
180 {
181     for(int j=1;j<=3;++j)
182     {
183         pai=Card[top++];
184         if(top>m) top=m;
185         switch(pai)
186         {
187             case 'J':
188                 pig[u].wuxie++;break;
189             case 'K':
190                 pig[u].sha++;break;
191             case 'D':
192                 pig[u].shan++;break;
193             case 'P':
194                 pig[u].tao++;break;
195         }
196         pig[u].tot++;
197         pig[u].card[++pig[u].rit]=pai;
198     }
199 }
200 
201 inline void diaoxie(int u,int now)//u使now掉血,处理死亡(不处理仇恨) 
202 {
203     pig[now].xie--;
204     if(pig[now].xie==0)
205     {
206         if(pig[now].tao)
207         {
208             pig[now].xie=1;
209             pig[now].tot--;
210             pig[now].tao--;
211             yongtao(now);
212         }
213         else
214         {
215             pig[now].liv=0;
216             if(pig[now].iden==3)
217             {
218                 win=2;
219                 return;
220             }
221             if(pig[now].iden==1)
222             {
223                 if(pig[u].iden==3)
224                 {
225                     pig[u].zhuge=0;
226                     pig[u].tao=pig[u].sha=pig[u].shan=pig[u].wuxie=0;
227                     for(int i=1;i<=pig[u].rit;++i)
228                         pig[u].used[i]=0;
229                     pig[u].rit=pig[u].tot=0;
230                     return;
231                 }
232             }
233             if(pig[now].iden==0)
234             {
235                 fan--;
236                 if(fan==0) 
237                 {
238                     win=1;
239                     return;
240                 }
241                 mosanzhang(u);
242             }
243         }
244     }
245 }
246 
247 inline void nanman(int u)//无仇恨,只类反 
248 {
249     int k=n-1,now=u;
250     while(k--)
251     {
252         now++;
253         if(now>n) now=1;
254         if(!pig[now].liv) continue;
255         if(!yongwuxie(now,1,u))
256         {
257             if(pig[now].sha>0)
258             {
259                 pig[now].sha--;
260                 pig[now].tot--;
261                 yongsha(now,1);
262             }
263             else
264             {
265                 diaoxie(u,now);
266                 if(pig[now].iden==3&&pig[u].biao==0)
267                     pig[u].leifan=1; 
268             } 
269         }
270         if(win) return;
271     }
272 }
273 
274 inline void wanjian(int u)
275 {
276     int k=n-1,now=u;
277     while(k--)
278     {
279         now++;
280         if(now>n) 
281             now=1;
282         if(!pig[now].liv) continue;
283         if(!yongwuxie(now,1,u))
284         {
285             if(pig[now].shan>0)
286             {
287                 pig[now].shan--;
288                 pig[now].tot--;
289                 yongshan(now);
290             }
291             else
292             {
293                 diaoxie(u,now);
294                 if(pig[now].iden==3&&pig[u].biao==0)
295                     pig[u].leifan=1; 
296             } 
297         }
298         if(win) return;
299     }
300 }
301 
302 inline int doumubiao(int u)
303 {
304     if(!pig[u].iden)
305         return 1;
306     int now=u,k=n-1;
307     while(k--)
308     {
309         now++;
310         if(now>n)
311             now=1;
312         if(!pig[now].liv) 
313             continue;
314         if(pig[now].biao==0)
315         {
316             if(u==1&&pig[now].leifan)
317                 return now;
318         }
319         else
320         {
321             if((pig[now].iden&1)!=(pig[u].iden&1))
322                 return now;
323         }
324     }
325     return 0;
326 }
327 
328 inline int juedou(int u,int now)//只计算掉血、杀 
329 {
330     if(u==1&&pig[now].iden)
331     {
332         diaoxie(1,now);
333         return 0;
334     }
335     if(yongwuxie(now,1,u)) 
336         return 0;
337     if(!pig[now].sha)
338     {
339         diaoxie(u,now);
340         return 0;
341     }
342     pig[now].sha--;
343     pig[now].tot--;
344     yongsha(now,1);
345 //    if(yongwuxie(u,1))
346 //        return 0;
347     if(!pig[u].sha)
348     {
349         diaoxie(now,u);
350         return 1;
351     }
352     pig[u].sha--;
353     pig[u].tot--;
354     yongsha(u,1);
355     if(pig[now].sha>pig[u].sha)
356     {
357         pig[now].sha-=pig[u].sha+1;
358         pig[now].tot-=pig[u].sha+1;
359         yongsha(now,pig[u].sha+1);
360         yongsha(u,pig[u].sha);
361         pig[u].tot-=pig[u].sha;
362         pig[u].sha=0;
363         diaoxie(now,u);
364         return 1;
365     }
366     else 
367     {
368         pig[u].sha-=pig[now].sha;
369         pig[u].tot-=pig[now].sha;
370         yongsha(u,pig[now].sha);
371         yongsha(now,pig[now].sha);
372         pig[now].tot-=pig[now].sha;
373         pig[now].sha=0;
374         diaoxie(u,now);
375         return 0;
376     }
377 }
378 
379 inline void zhengli(int u)
380 {
381     int ccnt=0;
382     for(int i=1;i<=pig[u].rit;++i)
383     {
384         if(!pig[u].used[i])
385             pig[u].card[++ccnt]=pig[u].card[i];
386         else
387             pig[u].used[i]=0;
388     }
389     pig[u].rit=ccnt;
390 }
391 
392 inline int nengyongsha(int u)
393 {
394     int k=n-1,now=u;
395     while(k--)
396     {
397         now++;
398         if(now>n) now=1;
399         if(!pig[now].liv) continue;
400         if(pig[u].iden==3)
401         {
402             if(pig[now].biao==1)
403             {
404                 if(pig[now].iden==0)
405                     return now;
406                 else
407                     return 0;
408             }
409             else
410                 if(pig[now].leifan)
411                     return now;
412                 else 
413                     return 0;
414         }
415         if(pig[now].biao==0) 
416             return 0;
417         if((pig[now].iden&1)!=(pig[u].iden&1)) 
418             return now;
419         else 
420             return 0;
421     }
422     return 0;
423 }
424 
425 inline void chupai(int u)
426 {
427     int t;
428     int weiyongdou=0,weiyongsha=0,weiyongtao=0;
429     liangshengfen=0;
430     usesha=0;
431     for(int i=1;i<=pig[u].rit;++i)
432     if(!pig[u].used[i])
433     {
434         switch(pig[u].card[i])
435         {
436             case 'N':
437                 pig[u].tot--;
438                 pig[u].used[i]=1;
439                 nanman(u);
440                 break;
441             case 'F':
442                 if(t=doumubiao(u))
443                 {
444                     pig[u].used[i]=1;
445                     pig[u].tot--;
446                     pig[u].biao=1;
447                     if(juedou(u,t))//自己掉血 
448                     {
449                         if(weiyongtao>0) 
450                         {
451                             yongtao(u);
452                             pig[u].xie++;
453                             pig[u].tao--;
454                             pig[u].tot--;
455                             weiyongtao--;
456                         }
457                     }
458                 }
459                 else
460                     weiyongdou=1;
461                 break;    
462             case 'W':
463                 pig[u].tot--;
464                 pig[u].used[i]=1;
465                 wanjian(u);
466                 break;
467             case 'Z':
468                     pig[u].zhuge=1;
469                     pig[u].used[i]=1;
470                     pig[u].tot--;
471                     break;
472             case 'D':break;
473             case 'J':break;
474             case 'P':
475                     if(pig[u].xie<4)
476                     {
477                         pig[u].xie++;
478                         pig[u].tao--;
479                         pig[u].used[i]=1;
480                     }
481                     else
482                         weiyongtao++;
483                     break;
484             case 'K':
485                 if(!usesha||(pig[u].zhuge))
486                 {
487                     if(t=nengyongsha(u))
488                     {
489                         usesha=1;
490                         pig[u].biao=1;
491                         pig[u].used[i]=1;
492                         pig[u].tot--;
493                         pig[u].sha--;
494                         if(pig[t].shan)
495                         {
496                             pig[t].shan--;
497                             yongshan(t);
498                             pig[t].tot--;
499                         }
500                         else
501                             diaoxie(u,t);
502                     }
503                     else
504                         weiyongsha=1;
505                 }
506                 else 
507                     weiyongsha=1;
508                 break;
509         }
510         if(!pig[u].liv)
511             return;
512         if(win) return;
513         if(liangshengfen&&weiyongdou)
514         {
515             liangshengfen=0;weiyongdou=0;
516             i=0;
517         }
518         else
519             if(weiyongsha&&(!usesha||pig[u].zhuge)&&nengyongsha(u))
520             {
521                 weiyongsha=0;
522                 i=0;
523             }
524     }
525     if(pig[u].rit>(pig[u].tot<<1))
526         zhengli(u);
527 }
528 
529 int main()
530 {
531     init();
532     int now=1;
533     while(!win)
534     {
535         if(pig[now].liv)
536         {
537             for(int j=1;j<=2;++j)
538             {
539                 pai=Card[top++];
540                 if(top>m) top=m;
541                 switch(pai)
542                 {
543                     case 'J':
544                         pig[now].wuxie++;break;
545                     case 'K':
546                         pig[now].sha++;break;
547                     case 'D':
548                         pig[now].shan++;break;
549                     case 'P':
550                         pig[now].tao++;break;
551                 }
552                 pig[now].tot++;
553                 pig[now].card[++pig[now].rit]=pai;
554             }
555             chupai(now);
556         }
557         now++;
558         if(now>n)
559             now=1;
560     }
561     if(win==1)
562         printf("MP\n");
563     else
564         printf("FP\n");
565     for(int i=1;i<=n;++i)
566     {
567         if(!pig[i].liv)
568             printf("DEAD\n");
569         else
570         {
571             for(int j=1;j<=pig[i].rit;++j)
572                 if(!pig[i].used[j])
573                 {
574                     printf("%c ",pig[i].card[j]);
575                 }
576             putchar('\n');
577         }
578     }
579     return 0;
580 }
580行AC代码警告
posted @ 2019-10-28 20:08  千叶繁华  阅读(383)  评论(0编辑  收藏  举报