BZOJ1972:[SDOI2010]猪国杀(模拟)

Description

太长就不贴过来了

Solution 

这个题是真的不难写……唯一的难度就在于理解题意上面……感觉这就是个阅读理解题啊……

而且你三国杀玩的越多可能就越难写因为你无法理解那些猪的思维……

Asia:这些猪会强制把你变得和他们一样sb,然后用他们丰富的sb经验来打败你

细节就不说了……说几个我写挂或者遗漏的点吧:

1、手牌不要从左扫到右扫完一遍就结束了……可能后面发生了什么事件导致你前面的牌又可以用了。

2、无懈可击的写法:我是不停的递归下去直到一方没有无懈可击为止 不知道有没有别的写法

3、牌堆没牌的话就不停摸牌堆最后一张,直到结束为止。这里好像题目里没有说……?

4、决斗无限距离且反贼只会直接去决斗刚主公

一些具体细节可以看代码实现……太多了就不说了……

Code

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<cstdio>
  5 #include<vector>
  6 #include<queue>
  7 #define N (15)
  8 using namespace std;
  9 
 10 struct Pig
 11 {
 12     int hp;//血量 
 13     int id;//真实身份 123主忠反 
 14     int id2;//跳明身份 01是否跳明 2类反 
 15     int bow;//是否装有武器
 16     vector<char>card;//可打出的手牌 
 17 }p[N];
 18 queue<char>q;//牌堆 
 19 char opt[3],a[2],b[2],c[2],d[2];
 20 int n,m,Fnum,cpos;
 21 
 22 void debug(int x)
 23 {
 24     cout<<x<<':';
 25     for (int i=0; i<p[x].card.size(); ++i)
 26         printf("%c ",p[x].card[i]);
 27     puts("");
 28 }
 29 
 30 void Print()
 31 {
 32     for (int i=1; i<=n; ++i)
 33         if (p[i].hp==0) puts("DEAD");
 34         else
 35         {
 36             for (int j=0; j<p[i].card.size(); ++j)
 37                 printf("%c ",p[i].card[j]);
 38             puts("");
 39         }
 40     exit(0);
 41 }
 42 
 43 int Dis(int x,int y)//计算距离 
 44 {
 45     int ans=1;
 46     for (int i=x%n+1; i!=y; i=i%n+1)
 47         if (p[i].hp>0) ans++;
 48     return ans;
 49 }
 50 
 51 void Solve(int from,int x,char opt,int cnt)//伤害来源,结算角色,需要的卡牌,需要的张数。 
 52 {
 53     for (int i=0; i<p[x].card.size();)
 54         if (p[x].card[i]!=opt || cnt==0) ++i;
 55         else p[x].card.erase(p[x].card.begin()+i),cnt--;
 56     if (cnt>0)
 57     {
 58         p[x].hp--;
 59         if (p[x].id==1 && !p[from].id2) p[from].id2=2;
 60     }
 61     if (p[x].hp==0)
 62     {
 63         for (int i=0; i<p[x].card.size();)
 64             if (p[x].card[i]!='P') ++i;
 65             else
 66             {
 67                 p[x].card.erase(p[x].card.begin()+i);
 68                 p[x].hp=1; break;
 69             }
 70         if (p[x].hp!=0) return;
 71         cpos=0;//有人死亡后手牌重新从最左开始扫 
 72         if (p[x].id==3) Fnum--;
 73         if (p[x].id==1)
 74             puts("FP"),Print();
 75         if (!Fnum)
 76             puts("MP"),Print();
 77             
 78         if (p[x].id==2 && p[from].id==1)
 79             p[from].bow=0, p[from].card.clear();
 80         if (p[x].id==3)
 81         {
 82             for (int i=1; i<=3; ++i)
 83             {
 84                 p[from].card.push_back(q.front());
 85                 if (q.size()>1) q.pop();
 86             }
 87         }
 88     }
 89 }
 90 
 91 bool check(int x,int y,int opt)//检查x对y是否合法,opt为将要进行的类型 1献殷勤2表敌意 
 92 {
 93     if (p[x].hp==0 || p[y].hp==0) return false;
 94     int idx=p[x].id==3?2:1;
 95     int idy=p[y].id==3?2:1;
 96     if (idx!=idy && p[y].id2==1 && opt==2) return true;
 97     if (idx==idy && p[y].id2==1 && opt==1) return true;
 98     if (p[y].id2==2 && p[x].id==1 && opt==2) return true;
 99     return false; 
100 }
101 
102 int WXKJ(int pos,int opt,int tar)//这一轮开始的位置,当前是否生效1生效2无效,目标
103 {
104     if (check(pos,tar,opt))
105         for (int i=0; i<p[pos].card.size();++i)
106             if (p[pos].card[i]=='J')
107             {
108                 if (p[pos].id2!=1) p[pos].id2=1,cpos=0;
109                 p[pos].card.erase(p[pos].card.begin()+i);
110                 return WXKJ(pos,opt==1?2:1,tar);
111             }
112         
113     for (int i=pos%n+1; i!=pos; i=i%n+1)
114         if (check(i,tar,opt))
115             for (int j=0; j<p[i].card.size();++j)
116                 if (p[i].card[j]=='J')
117                 {
118                     if (p[i].id2!=1) p[i].id2=1,cpos=0;
119                     p[i].card.erase(p[i].card.begin()+j);
120                     return WXKJ(i,opt==1?2:1,tar);
121                 }
122     return opt;
123 }
124 
125 int main()
126 {
127     scanf("%d%d",&n,&m);
128     for (int i=1; i<=n; ++i)
129     {
130         scanf("%s%s%s%s%s",opt,a,b,c,d);
131         if (opt[0]=='M') p[i].id=1,p[i].id2=1;
132         if (opt[0]=='Z') p[i].id=2;
133         if (opt[0]=='F') p[i].id=3,Fnum++;
134         p[i].hp=4;
135         p[i].card.push_back(a[0]); p[i].card.push_back(b[0]);
136         p[i].card.push_back(c[0]); p[i].card.push_back(d[0]);
137     }
138     for (int i=1; i<=m; ++i)
139         scanf("%s",a),q.push(a[0]);
140     if (!Fnum){puts("MP");Print();return 0;}
141 
142     int now=1;
143     while (1)
144     {
145         bool kill=false;
146         p[now].card.push_back(q.front());
147         if (q.size()>1) q.pop();    
148         p[now].card.push_back(q.front());
149         if (q.size()>1) q.pop();    
150 //        debug(now);
151         for (cpos=0; cpos<p[now].card.size();)
152         {
153             if (p[now].hp==0) break;
154             switch (p[now].card[cpos])
155             {
156                 case 'P'://
157                 {
158                     if (p[now].hp<4)
159                     {
160                         p[now].hp++;
161                         p[now].card.erase(p[now].card.begin()+cpos);
162                     }
163                      else ++cpos;
164                     break;
165                 }
166                 case 'K'://
167                 {
168                     if (kill && !p[now].bow){++cpos; break;}
169                     bool vis=false;
170                     for (int i=now%n+1; i!=now; i=i%n+1)
171                         if (check(now,i,2) && Dis(now,i)<=1)
172                         {
173                             vis=true; kill=true;
174                             p[now].card.erase(p[now].card.begin()+cpos);
175                             Solve(now,i,'D',1);
176                             if (p[now].id2!=1) p[now].id2=1,cpos=0;
177                             break;
178                         }
179                     if (!vis) ++cpos;
180                      break;
181                 }
182                 case 'F'://决斗 
183                 {
184                     bool vis=false;
185                     int tar=-1;
186                     if (p[now].id==3) tar=1;
187                     else
188                         for (int i=now%n+1; i!=now; i=i%n+1)
189                             if (check(now,i,2)){tar=i; break;}
190                     if (tar==-1){++cpos; break;}
191                     
192                     p[now].card.erase(p[now].card.begin()+cpos);
193                     if (p[now].id2!=1) p[now].id2=1,cpos=0;
194                     if (WXKJ(now,1,tar)==2) break;
195                     int cnt1=0,cnt2=0;
196                     for (int k=0; k<p[now].card.size(); ++k)
197                         if (p[now].card[k]=='K') cnt1++;
198                     for (int k=0; k<p[tar].card.size(); ++k)
199                         if (p[tar].card[k]=='K') cnt2++;
200                     if (p[now].id==1 && p[tar].id==2) 
201                         Solve(now,tar,'?',1);
202                     else
203                     {
204                         Solve(now,tar,'K',cnt1+1);
205                         Solve(tar,now,'K',cnt2);
206                     }
207                     break;
208                 }
209                 case 'N'://南蛮入侵 
210                 {
211                     p[now].card.erase(p[now].card.begin()+cpos);
212                     for (int i=now%n+1; i!=now; i=i%n+1)
213                     {
214                         if (p[i].hp==0) continue; 
215                         if (WXKJ(now,1,i)==2) continue;
216                         Solve(now,i,'K',1);
217                     }
218                      break;
219                 }
220                 case 'W'://万箭齐发 
221                 {
222                     p[now].card.erase(p[now].card.begin()+cpos);
223                     for (int i=now%n+1; i!=now; i=i%n+1)
224                     {
225                         if (p[i].hp==0) continue; 
226                         if (WXKJ(now,1,i)==2) continue;
227                         Solve(now,i,'D',1);
228                     }
229                      break;
230                 }
231                 case 'Z'://诸葛连弩 
232                 {
233                     p[now].bow=1;
234                     p[now].card.erase(p[now].card.begin()+cpos);
235                      cpos=0; break;
236                 }
237                 default: ++cpos;
238             }
239         }
240         now=now%n+1;
241         while (p[now].hp==0) now=now%n+1;
242     }
243 }
posted @ 2018-10-10 10:11  Refun  阅读(231)  评论(0编辑  收藏  举报