zoukankan      html  css  js  c++  java
  • [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 }
  • 相关阅读:
    Spring @Async开启异步任务
    Spring中@Async用法总结
    分布式任务调度平台XXL-JOB
    异常的概念和Java异常体系结构
    Java中主线程如何捕获子线程抛出的异常
    java主线程捕获子线程中的异常
    springboot线程池@Async的使用和扩展
    全面理解Java内存模型(JMM)及volatile关键字
    C++异常处理入门
    VC6下深入理解new[]和delete[](在多线程下new和delete的时候,必须选择上多线程库,不然可能造成进程崩溃)
  • 原文地址:https://www.cnblogs.com/eternhope/p/9895460.html
Copyright © 2011-2022 走看看