洛谷P2482 [SDOI2010]猪国杀 坑点总结

题目链接:https://www.luogu.com.cn/problem/P2482
总结了几个坑点…
(这种改一改都能当课设交的东西真的有人比赛的时候写得出来吗)

  • 使用锦囊牌时可能存在跳反或跳忠(打出无懈可击)的情况,一旦出现了有可能要从头检索是否有可使用的杀或决斗
  • 装备诸葛连弩时同理;
  • 对别人打出决斗自己可能会死,此时需要中断回合;
  • 反猪的决斗一定是对主猪用的;
  • 主猪杀了忠猪后,弃牌的时候不要忘了诸葛连弩;
  • 同时不要忘了此时遍历的手牌已经没了;
  • 但是不能直接中断回合,比如忠猪如果死于万箭齐发,那么在它之后还可能有反猪因此死掉,这种情况下主公会摸三张牌,回合仍可能继续;
  • 角色死后不要鞭尸,南蛮入侵、万箭齐发等需要遍历玩家的情况记得跳过死者;
  • 一有角色死亡就要记得计算距离;
  • 距离是单向的;
  • 牌堆如果没牌了会持续抽最后一张牌;
  • 无懈可击可以无限连;
  • 如果自身没有跳反/忠,那么无懈可击也不会对自己用
  • 使用过和决斗和无懈可击的角色身份一定是明确的
  • 反猪并不会帮助类反猪,如果忠猪被变成了类反猪被主猪决斗了那就只能挨打掉血
  • 由于角色死亡可能导致游戏结束,因此每次有角色死透了都要康康死的是不是主公或最后一个反贼

附上Ac代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

struct Player
{
   
    char card[2005];
    int mp_sign[15];
    int card_num=0,hp=4,card_cur=0,card_st=1;
    bool mp,zp,fp,weapon,expose;
    int wx,shan,atk;
    int uwx,u_shan;
}player[15];
char card[2005];
int n,cur=0,fst_kill,fst_jd;
bool fp_ep,zp_ep;

void get_card(int i,char ch)//获取卡牌
{
   
    player[i].card[++player[i].card_cur]=ch;
    ++player[i].card_num;
    if(ch=='J')
        ++player[i].wx;
    else if(ch=='D')
        ++player[i].shan;
}

int z_wx(const int &num,const int &n)//主公一派打出无懈
{
   
    for(int k=num,i=0;i<n;++i,k=k+1>n?1:k+1)
    {
   
        if(player[k].zp&&player[k].wx!=0&&player[k].hp>0)//活的忠臣
        {
   
            if(!player[k].expose)
                player[k].expose=zp_ep=true,player[1].mp_sign[k]=1;
            --player[k].card_num,--player[k].wx,++player[k].uwx;
            return k;
        }
        else if(player[k].mp&&player[k].wx!=0)//主公
        {
   
            --player[k].card_num,--player[k].wx,++player[k].uwx;
            return k;
        }
    }
    return -1;
}

int f_wx(const int &num,const int &n)//反贼一派打出无懈
{
   
    for(int k=num,i=0;i<n;++i,k=k+1>n?1:k+1)
    {
   
        if(player[k].fp&&player[k].wx!=0&&player[k].hp>0)//活的反贼
        {
   
            if(!player[k].expose)
                player[k].expose=fp_ep=true,player[1].mp_sign[k]=-1;
            --player[k].card_num,--player[k].wx,++player[k].uwx;
            return k;
        }
    }
    return -1;
}

void dying(const int &num,const int &m,const int &j)//濒死状态
{
   
    for(int i=player[j].card_st;i<=player[j].card_cur;++i)
    {
   
        if(player[j].card[i]=='P')//自救成功
        {
   
            ++player[j].hp,--player[j].card_num,player[j].card[i]=0;
            return ;
        }
    }
    if(player[j].mp)
        return ;
    int a=-1;
    for(int i=j-1>0?j-1:n;i!=j;i=i-1>0?i-1:n) //角色死亡导致距离改变
    {
   
        if(player[i].hp>0)
        {
   
            a=i;
            break;
        }
    }  
    for(int i=j+1>n?1:j+1;i!=j;i=i+1>n?1:i+1)  
    {
   
        if(player[i].hp>0)
        {
   
            player[a].atk=i;
            break;
        }
    }  
    if(player[j].fp)//反贼死亡,击杀者摸牌
    {
   
        cur=min(m,cur+1),get_card(num,card[cur]);
        cur=min(m,cur+1),get_card(num,card[cur]);
        cur=min(m,cur+1),get_card(num,card[cur]);
        return ;
    }
    if(player[j].zp&&player[num].mp)//主公杀死忠臣失去所有手牌
    {
   
        player[num].uwx=player[num].u_shan=0;
        player[num].card_num=player[num].wx=player[num].shan=0;
        player[num].card_st=player[num].card_cur+1;
        player[num].weapon=false,fst_jd=fst_kill=0;
        return ;
    }
}

bool jd(const int &a,const int &b)决斗判定
{
   
    while(true)
    {
   
        bool k_left=false;
        for(int j=player[b].card_st;j<=player[b].card_cur;++j)
        {
   
            if(player[b].card[j]=='K')
            {
   
                player[b].card[j]=0,--player[b].card_num,k_left=true;
                break;
            }
        }
        if(k_left)
        {
   
            k_left=false;
            for(int j=player[a].card_st;j<=player[a].card_cur;++j)
            {
   
                if(player[a].card[j
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值