bzoj1972: [Sdoi2010]猪国杀

传送门
这不就是三国杀的猪化版吗?
莫名蛋疼的模拟。
打了一个晚上,真

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm> 
using namespace std;
char heck[2001],ch[5];
int n,fnum,m,now,ed;
struct pig{
    bool f,jump,like;
    int hp,num;
    bool zhuge,used[2001];
    char hand[2001];
}a[15];
bool mp(int k){
    return !k;
}
bool zp(int k){
    return !a[k].f&&k;
}
bool fp(int k){
    return a[k].f;
}
void discard(int k){
    a[k].num=a[k].zhuge=0;
}
void init(){
    scanf("%d%d",&n,&m);
    for (int i=0;i<n;i++){
        scanf("%s",ch);
        if (ch[0]=='F'){
            a[i].f=1;
            fnum++;
        }
        for (int j=1;j<=4;j++)
            scanf(" %c",&a[i].hand[j]);
        a[i].num=a[i].hp=4;
    }
    for (int i=0;i<m;i++)
        scanf(" %c",&heck[i]);
    if (!fnum) ed=1;
}
int dis(int x,int y){
    int d=1;
    for (int i=(x+1)%n;i!=y;i=(i+1)%n)
        if (a[i].hp) d++;
    return d;
}
void reset(int k){
    int tot=0;
    for (int i=1;i<=a[k].num;i++)
        if (!a[k].used[i]){
            tot++;
            a[k].hand[tot]=a[k].hand[i];
            a[k].used[tot]=0;
        }
    a[k].num=tot;
}
void showhand(int k){
    reset(k);
    for (int i=1;i<=a[k].num;i++){
        printf("%c",a[k].hand[i]);
        if (i!=a[k].num) printf(" ");
    }
    printf("\n");
}
void gethand(int k,int num){
    if (ed) return;
    for (int i=1;i<=num;i++){
        a[k].num++;
        a[k].hand[a[k].num]=heck[now];
        a[k].used[a[k].num]=0;
        if (now<m-1) now++;
    }
}
void kill(int k,int from){
    if (mp(k)){
        ed=2;
        return;
    }
    if (fp(k)){
        fnum--;
        if (!fnum) ed=1;
        gethand(from,3);
    }
    if (zp(k)&&mp(from)) discard(from);
}
void jump(int k){
    a[k].jump=1;
}
bool usecard(int k,char c){
    for (int i=1;i<=a[k].num;i++)
        if (a[k].hand[i]==c&&!a[k].used[i]){
            a[k].used[i]=1;
            return 1;
        }
    return 0;
}
bool sha(int k){
    return usecard(k,'K');
}
bool shan(int k){
    return usecard(k,'D');
}
bool tao(int k){
    return usecard(k,'P');
}
bool wuxie(int k){
    if (usecard(k,'J')){
        jump(k);
        return 1;
    }
    return 0;
}
void like(int k){
    if (!a[k].jump) a[k].like=1;
}
void wound(int k,int from){
    a[k].hp--;
    if (!a[k].hp){
        if (tao(k)) a[k].hp=1;
        else kill(k,from);
    }
}
bool askwuxie(int k,int f){
    int i=k;
    while (1){
        if (a[i].hp&&a[i].f==f)
            if (wuxie(i)){
                if (!askwuxie(i,f^1)) return 1;
                return 0;
            }
        i=(i+1)%n;
        if (i==k) return 0;
    }
}
bool needwuxie(int k,int from){
    if (!a[k].jump&&!mp(k)) return 0;
    if (askwuxie(from,a[k].f)) return 1;
    return 0;
}
void aoe(int k,int f){
    for (int i=(k+1)%n;i!=k;i=(i+1)%n)
        if (a[i].hp){
            if (needwuxie(i,k)) continue;
            if (f==1){
                if (!sha(i)){
                    if (mp(i)) like(k);
                    wound(i,k);
                }
            }
            if (f==2){
                if (!shan(i)){
                    if (mp(i)) like(k);
                    wound(i,k);
                }
            }
            if (ed) return;
        }
}
int duel(int k,int from){
    if (zp(k)&&mp(from)) return 1;
    if (needwuxie(k,from)) return 2;
    while (1){
        if (!sha(k)) return 1;
        if (!sha(from)) return 0;
    }
}
bool attack(int k,int f){
    if (fp(k)){
        if (dis(k,0)==1&&f==1){
            jump(k);
            if (!shan(0)) wound(0,k);
            return 1;
        }
        if (f==2){
            jump(k);
            int res=duel(0,k);
            if (res==1) wound(0,k);
            else if (res==0) wound(k,0);
            return 1; 
        }
    }
    if (mp(k)){
        for (int i=(k+1)%n;i!=k;i=(i+1)%n)
            if (a[i].hp)
                if ((fp(i)&&a[i].jump)||(a[i].like&&!a[i].jump)){
                    if (dis(k,i)==1&&f==1){
                        if (!shan(i)) wound(i,k);
                        return 1;
                    }
                    if (f==2){
                        int res=duel(i,k);
                        if (res==1) wound(i,k);
                        else if (res==0) wound(k,i);
                        return 1;
                    }
                }
    }
    else{
        for (int i=(k+1)%n;i!=k;i=(i+1)%n)
            if (a[i].hp)
                if ((a[k].f^a[i].f)&&a[i].jump){
                    if (dis(k,i)==1&&f==1){
                        jump(k);
                        if (!shan(i)) wound(i,k);
                        return 1;
                    }
                    if (f==2){
                        jump(k);
                        int res=duel(i,k);
                        if (res==1) wound(i,k);
                        else if (res==0) wound(k,i);
                        return 1;
                    }
                }   
    }
    return 0;
}
void move(int k){
    reset(k);
    gethand(k,2);
    bool flag=0;
    for (int i=1;i<=a[k].num;i++){
        if (ed||!a[k].hp) return;
        if (a[k].used[i]==1) continue;
        if (a[k].hand[i]=='P'&&a[k].hp<4){
            //printf("%d tao\n",i);
            a[k].used[i]=1;
            a[k].hp++;
        }
        else if (a[k].hand[i]=='N'){
            //printf("%d nanzhu\n",i);
            a[k].used[i]=1;
            aoe(k,1);
            i=0;
        }
        else if (a[k].hand[i]=='W'){
            //printf("%d wanjian\n",i);
            a[k].used[i]=1;
            aoe(k,2);
            i=0;
        }
        else if (a[k].hand[i]=='K'&&(!flag||a[k].zhuge)){
            if (attack(k,1)){
                //printf("%d sha\n",i);
                a[k].used[i]=1;
                flag=1;
                i=0;
            }
        }
        else if (a[k].hand[i]=='F'){
            if (attack(k,2)){
                a[k].used[i]=1;
                i=0;
            }
        }
        else if (a[k].hand[i]=='Z'){
            a[k].used[i]=1;
            if (!a[k].zhuge){
                a[k].zhuge=1;
                i=0;
            }
        }
    }
}
void print(){
    if (ed==1) printf("MP\n");
    else if (ed==2) printf("FP\n");
    for (int i=0;i<n;i++)
        if (!a[i].hp) printf("DEAD\n");
        else showhand(i);
}
void solve(){
    for (int i=0;i<n;i++)
        if (a[i].hp) move(i);
    //print();
}
int main(){
    init();
    while (!ed) solve();
    print();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值