zoukankan      html  css  js  c++  java
  • 「SDOI2010」猪国杀:模拟

    $Description:$

    游戏背景

    《猪国杀》是一种多猪牌类回合制游戏,一共有 种角色:主猪,忠猪,反猪。每局游戏主猪有且只有 只,忠猪和反猪可以有多只,每只猪扮演 种角色。

    游戏目的

    主猪 /MP:自己存活的情况下消灭所有的反猪。
    忠猪 /ZP:不惜一切保护主猪,胜利条件与主猪相同。
    反猪 /FP:杀死主猪。

    游戏过程

    游戏开始时,每个玩家手里都会有 张牌,且体力上限和初始体力都是 。

    开始游戏时,从主猪开始,按照逆时针方向(数据中就是按照编号从 的顺序)依次行动。

    每个玩家自己的回合可以分为 2 个阶段:

    • 摸牌阶段:从牌堆顶部摸 张牌,依次放到手牌的最右边;
    • 出牌阶段:你可以使用任意张牌,每次使用牌的时候都使用最靠左的能够使用的牌。当然,要满足如下规则:
      1. 如果没有猪哥连弩,每个出牌阶段只能使用 次「杀」来攻击;
      2. 任何牌被使用后被弃置(武器是装备上);被弃置的牌以后都不能再用,即与游戏无关。

    各种牌介绍

    每张手牌用 个字母表示,字母代表牌的种类。

    基本牌

    • 『桃 /P』在自己的回合内,如果自己的体力值不等于体力上限,那么使用 个桃可以为自己补充 点体力,否则不能使用桃;桃只能对自己使用;在自己的回合外,如果自己的血变为 或者更低,那么也可以使用。

    • 『杀 /K』在自己的回合内,对攻击范围内除自己以外的 名角色使用。如果没有被『闪』抵消,则造成 点伤害。无论有无武器,杀的攻击范围都是 。

    • 『闪 /D』当你受到杀的攻击时,可以弃置 张闪来抵消杀的效果。

    锦囊牌

    • 『决斗 /F』出牌阶段,对除自己以外任意 名角色使用,由目标角色先开始,自己和目标角色轮流弃置 张杀,首先没有杀可弃的一方受到 点伤害,另一方视为此伤害的来源。

    • 『南猪入侵 /N』出牌阶段,对除你以外所有角色使用,按逆时针顺序从使用者下家开始依次结算,除非弃置 张杀,否则受到 点伤害。

    • 『万箭齐发 /W』和南猪入侵类似,不过要弃置的不是杀而是闪。

    • 『无懈可击 /J』在目标锦囊生效前抵消其效果。每次有 张锦囊即将生效时,从使用这张锦囊的猪开始,按照逆时针顺序,依次得到使用无懈可击的机会;效果:用于决斗时,决斗无效并弃置;用于南猪入侵或万箭齐发时,当结算到某个角色时才能使用,当前角色不需弃置牌并且不会受到伤害(仅对 个角色产生效果);用于无懈可击时,成为目标的无懈可击被无效。

    装备牌

    • 『猪哥连弩 /Z』武器,攻击范围 ,出牌阶段你可以使用任意张杀; 同一时刻最多只能装 把武器;如果先前已经有了 把武器,那么之后再装武器的话,会弃置以前的武器来装现在的武器。

    特殊事件及概念解释

    • 伤害来源:杀、南猪入侵、万箭齐发的伤害来源均是使用该牌的猪,决斗的伤害来源如上;

    • 距离:两只猪的距离定义为沿着逆时针方向间隔的猪数 。即初始时 和 的距离为 ,但是 和 的距离就是 。注意一个角色的死亡会导致一些猪距离的改变;

    • 玩家死亡:如果该玩家的体力降到 或者更低,并且自己手中没有足够的桃使得自己的体力值回到 ,那么就死亡了,死亡后所有的牌(装备区,手牌区)被弃置;

    • 奖励与惩罚:反猪死亡时,最后一个伤害来源处(即使是反猪)立即摸 张牌。忠猪死亡时,如果最后一个伤害来源是主猪,那么主猪所有装备牌、手牌被弃置。

    • *注意:*一旦达成胜利条件,游戏立刻结束,因此即使会摸 张牌或者还有牌可以用也不用执行了。

    现在,我们已经知道每只猪的角色、手牌,还有牌堆初始情况,并且假设每个角色会按照如下的行为准则进行游戏,你需要做的就是告诉小猪 iPig 最后的结果。

    几种行为

    • 献殷勤:使用无懈可击挡下南猪入侵、万箭齐发、决斗;使用无懈可击抵消表敌意;
    • 表敌意:对某个角色使用杀、决斗;使用无懈可击抵消献殷勤;
    • 跳忠:即通过行动表示自己是忠猪。跳忠行动就是对主猪或对某只已经跳忠的猪献殷勤,或者对某只已经跳反的猪表敌意;
    • 跳反:即通过行动表示自己是反猪。跳反行动就是对主猪或对某只已经跳忠的猪表敌意,或者对某只已经跳反的猪献殷勤。

    *注意:*忠猪不会跳反,反猪也不会跳忠;不管是忠猪还是反猪,能够跳必然跳。

    行动准则

    共性

    • 每个角色如果手里有桃且生命值未满,那么必然吃掉;
    • 有南猪入侵、万箭齐发、必然使用;有装备必然装上;
    • 受到杀时,有闪必然弃置;
    • 响应南猪入侵或者万箭齐发时候,有杀 / 闪必然弃置;
    • 不会对未表明身份的猪献殷勤(包括自己)。

    特性

    • 主猪:
    • 主猪会认为「没有跳身份,且用南猪入侵 / 万箭齐发对自己造成伤害的猪」是反猪(没伤害到不算,注意类反猪并没有表明身份),如果之后跳了,那么主猪会重新认识这只猪;
    • 对于每种表敌意的方式,对逆时针方向能够执行到的第一只类反猪或者已跳反猪表;如果没有,那么就不表敌意;
    • 决斗时会不遗余力弃置杀;
    • 如果能对已经跳忠的猪或自己献殷勤,那么一定献;如果能够对已经跳反的猪表敌意,那么一定表。
    • 忠猪:
    • 对于每种表敌意的方式,对「逆时针方向能够执行到的第一只已经跳反的猪」表,如果没有,那么就不表敌意;
    • 决斗时,如果对方是主猪,那么不会弃置杀,否则,会不遗余力弃置杀;
    • 如果有机会对主猪或者已经跳忠的猪献殷勤,那么一定献。
    • 反猪:
    • 对于每种表敌意的方式,如果有机会则对主猪表,否则,对「逆时针方向能够执行到的第一只已经跳忠的猪」表,如果没有,那么就不表敌意;
    • 决斗时会不遗余力弃置杀;
    • 如果有机会对已经跳反的猪献殷勤,那么一定献。
    限于 iPig 只会用 P++ 语言写 A + B,他请你用 Pigcal (Pascal)、P (C) 或 P++ (C++) 语言来帮他预测最后的结果

    $n le 10,m le 2000$。模拟的数据范围很重要吗?

    感觉自己要升仙了。

    寒假期间码力极差,几场模拟测试基本都是想到了然后写不出来。

    于是就抽了点零零散散的时间去写了写打模拟提升一下码力。

    其实并没有想象中那么难写,当然也好写不到哪里去。

    主要是读题与细节容易致错。

    得亏loj给数据了,不然这题还怎么调?就差自己跟自己玩起来了。

    其实只要读懂题问题就不大,大模拟并没有什么技术含量。

    只不过是纯粹的恶心。合计着带写带调用了4小时。

    一些细节:

    • 主猪杀忠猪要丢装备
    • loj题面里反猪名字是AP然而读入里是FP(坑死我,代码乱糟糟)
    • 要经常更新伤害来源
    • 打出手牌后可能会使某些猪死亡,或者身份暴露,此时可能有其它手牌可以打出,要从头遍历
    • 不能把桃/闪之类的数量提出来特殊处理,因为最后要按顺序输出手牌
    • 要注意谁正在挨打,谁即将使用无懈可击,不要乱
    • 一头猪可能通过决斗在自己回合挂掉,这时候要让他立刻停止出牌
    • 反猪攻击忠猪和主猪的优先级是不一样的,它的决斗优先对着主猪打出
    • 锦囊牌的描述不是很清楚:
    • 决斗时,在双方出杀之前,从使用者开始逆时针有机会打出。一旦开始出杀就必定有一方受伤。
    • 而决斗视为使用者对被使用者的攻击,不管最终结局如何,其他人都只会从被决斗者的角度来考虑是否无懈可击。
    • 南猪入侵和万箭齐发也是优先出无懈可击,其次才是杀和闪
    • 无懈可击的递归调用可以写作三个参数:目前轮到$P$考虑是否出无懈可击,如果他出了那么$p$将会收到$op=0/1$伤害,否则$1/0$

    其实没啥。这些问题猜也能猜到。。。

    但是题意没理解明白打大模拟心里肯定是慌的。

    其实代码也不是特别长,相较于联赛写的什么$lct$维护$SAM$之类乱七八糟的东西,$3.6k$会渐渐成为常态的吧。

    码力的确还是有点弱。还得多写写。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define X nxt[p]
     4 int S,FP[11],ZP[11],MP[11],fp[11],hp[11],TFP[11],TZP[11],handt[11],alu[11][2222],alcard=1,died[11],n,m,fpcnt,equip[11],nxt[11];
     5 char card[2222][3],hand[11][2222],res[3];
     6 void result(){
     7     for(int i=1;i<=n;++i)if(died[i])puts("DEAD");
     8         else{for(int j=1;j<=handt[i];++j)if(!alu[i][j])cout<<hand[i][j]<<' ';puts("");}
     9     exit(0);
    10 }
    11 void get_card(int p){handt[p]++,alu[p][handt[p]]=0,hand[p][handt[p]]=card[alcard][0];alcard++;alcard=min(alcard,m);}
    12 void damage(int p){
    13     hp[p]--;
    14     if(hp[p]>0)return;
    15     for(int i=1;i<=handt[p];++i)if(hand[p][i]=='P'&&!alu[p][i]){hp[p]++,alu[p][i]=1;break;}
    16     if(hp[p]>0)return; died[p]=1;
    17     if(MP[p])puts("FP"),result();
    18     if(FP[p]){fpcnt--;if(!fpcnt)puts("MP"),result();else for(int i=1;i<=3;++i)get_card(S);}
    19     if(ZP[p]&&MP[S]){equip[S]=0;for(int i=1;i<=handt[S];++i)alu[S][i]=1;}
    20     int lst; for(int i=n;i;--i)if(!died[i]){lst=i;break;}
    21     for(int i=1;i<=n;++i)if(!died[i])nxt[lst]=i,lst=i;
    22 }
    23 bool J(int p,int P,int op=0){
    24     for(int i=1;i<=handt[P];++i)if(hand[P][i]=='J'&&!alu[P][i])
    25     if(    (MP[P]&&(((TFP[p]||fp[p])&&op)||((TZP[p]||MP[p])&&!op))) ||
    26         (ZP[P]&&((TFP[p]&&op)||(((TZP[p]||MP[p]))&&!op))) ||
    27         (FP[P]&&((TFP[p]&&!op)||(((TZP[p]||MP[p]))&&op)))
    28     ){alu[P][i]=1; if(ZP[P])TZP[P]=1,fp[P]=0; if(FP[P])TFP[P]=1;
    29         for(int i=X;i!=P;i=nxt[i])if(J(p,i,op^1))return 0;
    30         return 1;
    31     }return 0;
    32 }
    33 void N(int p){
    34     for(int i=X;i!=p;i=nxt[i]){
    35         if(J(i,p))continue;
    36         for(int j=X;j!=p;j=nxt[j])if(J(i,j))goto P;
    37         for(int j=1;j<=handt[i];++j)if(hand[i][j]=='K'&&!alu[i][j]){alu[i][j]=1;goto P;}
    38         damage(i);if(MP[i]&&!TZP[p])fp[p]=1;P:;
    39     }
    40 }
    41 void W(int p){
    42     for(int i=X;i!=p;i=nxt[i]){
    43         if(J(i,p))continue;
    44         for(int j=X;j!=p;j=nxt[j])if(J(i,j))goto P;
    45         for(int j=1;j<=handt[i];++j)if(hand[i][j]=='D'&&!alu[i][j]){alu[i][j]=1;goto P;}
    46         damage(i);if(MP[i]&&!TZP[p])fp[p]=1;P:;
    47     }
    48 }
    49 bool F(int p){
    50     int g=0;
    51     if(FP[p])for(int i=1;i<=n;++i)if(MP[i])g=i;
    52     if(ZP[p])for(int i=X;i!=p;i=nxt[i])if(TFP[i]){g=i;break;}
    53     if(MP[p])for(int i=X;i!=p;i=nxt[i])if(TFP[i]||fp[i]){g=i;break;}
    54     if(!g)return 0; if(ZP[p])TZP[p]=1,fp[p]=0; if(FP[p])TFP[p]=1;
    55     for(int i=X;i!=p;i=nxt[i])if(J(g,i))return 1;
    56     while(1){E:
    57         if(ZP[g]&&MP[p])goto F;
    58         for(int i=1;i<=handt[g];++i)if(hand[g][i]=='K'&&!alu[g][i]){alu[g][i]=1;swap(g,p);goto E;}
    59         F:S=p;damage(g);return 1;
    60     }
    61 }
    62 void K(int p){
    63     for(int i=1;i<=handt[p];++i)if(hand[p][i]=='D'&&!alu[p][i])return void(alu[p][i]=1);
    64     damage(p);
    65 }
    66 void Round(int p){
    67     int alk=0;
    68     #define use alu[p][i]=1,i=0
    69     for(int i=1;i<=2;++i)get_card(p);
    70     for(int i=1;S=p,i<=handt[p]&&!died[p];++i)if(!alu[p][i])
    71         if(hand[p][i]=='P'){if(hp[p]<4)hp[p]++,use;}
    72         else if(hand[p][i]=='K'&&(alk==0||equip[p])){
    73             if(MP[p])if(TFP[X]||fp[X])use,K(X),alk++;
    74             if(ZP[p])if(TFP[X])use,TZP[p]=1,fp[p]=0,K(X),alk++;
    75             if(FP[p])if(TZP[X]||MP[X])use,TFP[p]=1,K(X),alk++;
    76         }else if(hand[p][i]=='F'){alu[p][i]=1;if(!F(p))alu[p][i]=0;else i=0;}
    77         else if(hand[p][i]=='N')use,N(p);
    78         else if(hand[p][i]=='W')use,W(p);
    79         else if(hand[p][i]=='Z')use,equip[p]=1;
    80 }
    81 main(){cin>>n>>m;
    82     for(int i=1;i<=n;++i){
    83         cin>>res;
    84         ZP[i]=res[0]=='Z';FP[i]=res[0]=='F';MP[i]=res[0]=='M';handt[i]=hp[i]=4;fpcnt+=res[0]=='F';
    85         for(int j=1;j<=4;++j)cin>>res,hand[i][j]=res[0]; nxt[i]=i+1;
    86     }nxt[n]=1;
    87     for(int i=1;i<=m;++i)cin>>card[i];
    88     for(int i=1;;i=nxt[i])if(!died[i])Round(i);
    89 }
    View Code
  • 相关阅读:
    DPDK安装方法 17.12.13
    numa.h:No such file or directory 解决方法
    17秋 软件工程 第六次作业 Beta冲刺 Scrum3
    17秋 软件工程 第六次作业 Beta冲刺 总结博客
    17秋 软件工程 第六次作业 Beta冲刺 Scrum2
    Paper Reviews and Presentations
    17秋 软件工程 第六次作业 Beta冲刺 Scrum1
    17秋 软件工程 第六次作业 Beta冲刺
    error: could not create '/System/Library/Frameworks/Python.framework/Versions/2.7/share': Operation not permitted
    17秋 软件工程 个人作业 软件产品案例分析
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/12315680.html
Copyright © 2011-2022 走看看