[SDOI2010] 猪国杀

NOIp前最后皮一下,祝自己RP++。

从昨天晚上开始写,一直写到现在才A......

在LXD大佬的帮助下,终于A掉了......

还发现有两道大模拟,一个是琪露诺的冰雪小屋,一个是杀蚂蚁,有兴趣的可以看一下。

先说这个猪国杀:

洛谷 P2482 传送门

我写了几个指针只是为了简化代码QAQ。

这道题题意挺清楚的,我就说几个坑点。

一个是如果牌堆里没牌了,要一直拿最后一个。

还有就是,决斗的伤害来源是受到伤害的人的另一个人,决斗不会出现自己伤害自己的情况。

如果有人掉血要立即判断是否死亡。

如果有人死亡要立即判断游戏是否结束。

如果能结束要立即结束,不要有其它摸牌或出牌的操作。

用函数封装一些操作能有效缩减代码长度,方便调试及查错。

像我就只写了不到300行,5kb左右。感觉还是挺简洁的,何况还没怎么过分压行。

感觉代码可读性还是很强的,就没写注释。

特别需要注意无懈可击的写法,要寻找是否有人想出无懈。

如果有,还要继续递归地无懈下去。

最后还要有返回值判断这个无懈最终是否会有效果。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 
  7 int n,m;
  8 
  9 int inv(int fr,int kd);
 10 int findinv(int st,int kd);
 11 void kill(int fr,int to);
 12 void duel(int fr,int to);
 13 void check();
 14 void end(int result);
 15 
 16 struct SCARDS
 17 {
 18     char cds[2005];int tp;
 19     char give()
 20     {
 21         if(tp==m)return cds[m];
 22         return cds[tp++];
 23     }
 24 }cards;
 25 
 26 struct SPIG
 27 {
 28     int hp,cnt,num;char card[2005],id[5];
 29     bool crossbow,antilike,anti,faith,dead;
 30     SPIG *last,*nx;
 31     void getcard(){card[++cnt]=cards.give();}
 32     void getcard(char cd){card[++cnt]=cd;}
 33     bool known(){return (anti||faith);}
 34     bool has(char cd)
 35     {
 36         for(int i=1;i<=cnt;i++)
 37             if(card[i]==cd)return 1;
 38         return 0;
 39     }
 40     void use(char cd)
 41     {
 42         for(int i=1;i<=cnt;i++)
 43             if(card[i]==cd){card[i]='x';return;}
 44     }
 45     void extort(char crd)
 46     {
 47         SPIG* pt=nx;
 48         while(pt!=this)
 49         {
 50             int k=0;
 51             if(pt->anti)k=findinv(num,0);
 52             if(pt->faith)k=findinv(num,1);
 53             if(k)k=inv(k,(pt->faith));
 54             if(!k)
 55             {
 56                 if(pt->has(crd))pt->use(crd);
 57                 else
 58                 {
 59                     pt->hurt(num);
 60                     if(pt->id[1]=='M'&&(!known()))
 61                         antilike=1;
 62                 }
 63             }
 64             pt=pt->nx;
 65         }
 66     }
 67     void play()
 68     {
 69         getcard();getcard();
 70         bool kl=0;
 71         for(int i=1;i<=cnt&&(!dead);i++)
 72         {
 73             if(card[i]=='x'||card[i]=='D')continue;
 74             if(card[i]=='Z')card[i]='x',crossbow=1,i=0;
 75             if(card[i]=='P'&&hp<4)card[i]='x',hp++;
 76             if(card[i]=='N')card[i]='x',extort('K'),i=0;
 77             if(card[i]=='W')card[i]='x',extort('D'),i=0;
 78             if(card[i]=='K'&&((!kl)||crossbow))
 79             {
 80                 if(id[1]=='M')
 81                     if(nx->antilike||nx->anti)
 82                         card[i]='x',kill(num,nx->num),kl=1,i=0;
 83                 if(id[1]=='Z')
 84                     if(nx->anti)
 85                         card[i]='x',kill(num,nx->num),kl=1,i=0;
 86                 if(id[1]=='F')
 87                     if((nx->faith)||(nx->id[1]=='M'))
 88                         card[i]='x',kill(num,nx->num),kl=1,i=0;
 89             }
 90             if(card[i]=='F')
 91             {
 92                 if(id[1]=='M')
 93                 {
 94                     SPIG *pt=nx;
 95                     while(pt!=this)
 96                     {
 97                         if((pt->antilike)||(pt->anti))
 98                         {
 99                             card[i]='x';
100                             duel(num,pt->num),i=0;
101                             break;
102                         }
103                         pt=(pt->nx);
104                     }
105                 }
106                 if(id[1]=='Z')
107                 {
108                     SPIG *pt=nx;
109                     while(pt!=this)
110                     {
111                         if(pt->anti)
112                         {
113                             card[i]='x';
114                             duel(num,pt->num),i=0;
115                             break;
116                         }
117                         pt=(pt->nx);
118                     }
119                 }
120                 if(id[1]=='F')card[i]='x',duel(num,1),i=0;
121             }
122         }
123     }
124     bool save()
125     {
126         if(has('P'))return use('P'),hp++,1;
127         return 0;
128     }
129     void hurt(int cause);
130 }pig[15];
131 
132 void SPIG::hurt(int cause)
133 {
134     hp--;
135     if(hp)return;
136     if(save())return;
137     dead=1;
138     check();
139     last->nx=nx;nx->last=last;
140     if(pig[cause].dead)return;
141     if(id[1]=='Z'&&pig[cause].id[1]=='M')
142     {
143         for(int i=1;i<=pig[cause].cnt;i++)
144             pig[cause].card[i]='x';
145         pig[cause].crossbow=0;
146     }
147     if(id[1]=='F')
148         for(int i=1;i<=3;i++)
149             pig[cause].getcard();
150 }
151 
152 void kill(int fr,int to)
153 {
154     if(pig[to].has('D'))pig[to].use('D');
155     else pig[to].hurt(fr);
156     if(pig[to].id[1]=='M'||pig[to].faith)
157         pig[fr].anti=1;
158     if(pig[to].anti)
159         pig[fr].faith=1,pig[fr].antilike=0;
160 }
161 
162 void duel(int fr,int to)
163 {
164     if(pig[fr].id[1]=='M'&&pig[to].id[1]=='Z')
165         {pig[to].hurt(fr);return;}
166     int k=0;
167     if(pig[fr].id[1]!='M')
168     {
169         if(pig[to].anti)pig[fr].faith=1,pig[fr].antilike=0;
170         else pig[fr].anti=1;
171     }
172     if(pig[to].anti)k=findinv(fr,0);
173     if(pig[to].faith)k=findinv(fr,1);
174     if(k)k=inv(k,pig[to].faith);
175     if(!k)
176     {
177         int fir=to,sec=fr;
178         while(1)
179         {
180             if(pig[fir].has('K'))
181                 pig[fir].use('K'),fir^=sec^=fir^=sec;
182             else
183                 {pig[fir].hurt(sec);break;}
184         }
185     }
186 }
187 
188 int inv(int fr,int kd)
189 {
190     pig[fr].use('J');
191     if(kd)pig[fr].faith=1,pig[fr].antilike=0;
192     else pig[fr].anti=1;
193     int k=findinv(fr,1-kd);
194     if(k)return 1-inv(k,1-kd);
195     else return 1;
196 }
197 
198 int findinv(int st,int kd)
199 {
200     SPIG* pt=&pig[st];
201     do
202     {
203         if((!kd)&&pt->id[1]=='F'&&pt->has('J'))
204             return pt->num;
205         if(kd&&(pt->id[1]=='Z'||pt->id[1]=='M')&&pt->has('J'))
206             return pt->num;
207         pt=pt->nx;
208     }while(pt->num!=st);
209     return 0;
210 }
211 
212 void check()
213 {
214     bool good=0,bad=0;
215     for(int i=1;i<=n;i++)
216     {
217         if(pig[i].id[1]=='M'&&pig[i].dead)end(0);
218         if(!pig[i].dead)
219         {
220             if(pig[i].id[1]=='F')bad=1;
221             else good=1;
222         }
223         if(good&&bad)return;
224     }
225     end(good);
226 }
227 
228 void end(int result)
229 {
230     if(result)printf("MP
");
231     else printf("FP
");
232     for(int i=1;i<=n;i++)
233     {
234         if(pig[i].dead)printf("DEAD");
235         else
236             for(int j=1;j<=pig[i].cnt;j++)
237                 if(pig[i].card[j]!='x')
238                     printf("%c ",pig[i].card[j]);
239         printf("
");
240     }
241     exit(0);
242 }
243 
244 int main()
245 {
246     scanf("%d%d",&n,&m);
247     for(int i=1;i<=n;i++)
248     {
249         scanf("%s",pig[i].id+1);
250         for(int j=1;j<=4;j++)
251         {
252             char cd[5];
253             scanf("%s",cd+1);
254             pig[i].getcard(cd[1]);
255         }
256         pig[i].hp=4;pig[i].num=i;
257         if(i==n)pig[i].nx=&pig[1];
258         else pig[i].nx=&pig[i+1];
259         if(i==1)pig[i].last=&pig[n];
260         else pig[i].last=&pig[i-1];
261     }
262     pig[1].faith=1;cards.tp=1;
263     for(int i=1;i<=m;i++)
264     {
265         char tmp[5];
266         scanf("%s",tmp+1);
267         cards.cds[i]=tmp[1];
268     }
269     check();
270     while(true)
271         for(int i=1;i<=n;i++)
272             if(!pig[i].dead)pig[i].play();
273 }
原文地址:https://www.cnblogs.com/eternhope/p/9895460.html