zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    discuz常用变量
    Discuz!X/模板标签说明
    Discuz x 默认模板文件目录说明
    apache禁止访问文件或目录执行权限、禁止运行脚本PHP文件的设置方法
    基于Java的数据采集(三)
    基于Java的数据采集(二)
    基于Java的数据采集(一)
    使用Spring JDBCTemplate简化JDBC的操作
    基于原生PHP交叉会员权限控制
    PHP上传压缩包并自解压方法
  • 原文地址:https://www.cnblogs.com/refun/p/9764769.html
Copyright © 2011-2022 走看看