[SDOI2010] pig country to kill problem solution

Topic links:

Luo Gu P2482

loj2885

bzoj1972

Loj recommended to look at the question, can the next dataBecause especially prone to error

sol

In fact, this problem is also not that large amount of code, after formatting my code only 141 lines, in loj the current minimum. More preferably a number of multi-function, for each pig had a structure.

Game over, some of the array / variable

The reason to write the end of the beginning, because after use.

void end() {
    puts(a[1].xue?"MP":"FP");//判断输赢
    for(int i=1; i<=n; i++) {//输出每只猪的状态
        if(a[i].xue==0)puts("DEAD");
        else {
            for(int j=0; j<a[i].s-1; j++)
                printf("%c ",a[i].pai[j]);
            if(a[i].s)printf("%c",a[i].pai[a[i].s-1]);
            puts("");
        }
    }
    exit(0);//退出整个程序
}

Array / Variable

int nxt[15],las[15],top,f,n,m;
//nxt,las为链表,后会解释,top为牌堆顶,f为反猪数量,n为总猪数,m为总牌数
char tem[5],paidui[2010];//tem用来输入,paidui就是牌堆

Each pig structure:

struct pig {
    char tp,pai[2010];//tp:真实身份,M主猪,Z忠猪,F反猪,pai:手牌
    int xue,s,z,t;
    //xue:血量,s:牌数,z:是否有猪哥连弩(Z),t:表面身份,0:未知,1:忠猪,2:反猪,3:类反猪
    void qizhi(int &x) {//将第x张牌弃置
        s--;
        for(int i=x; i<s; i++)
            pai[i]=pai[i+1];
        x--;
    }
    int seach(char ch) {//搜索第一张为ch的牌,有就弃置,返回1,否则返回0
        for(int i=0; i<s; i++)
            if(pai[i]==ch) {
                qizhi(i);
                return 1;
            }
        return 0;
    }
    void mopai(int x) {//从牌堆中摸x张牌
        for(int i=1; i<=x; i++) {
            pai[s++]=paidui[top++];
            if(top==m)top--;
        }
    }
} a[15];

I abandoned violence is deleted, can be used vector<char>, then Mopai have a bug, brand is not enough, to have been touched last card.

Gallant, table hostility, loyalty jump, jump Anti

The first definetwo statements

#define dipig(x,y) ((a[x].tp=='M'&&(a[y].t==2||a[y].t==3))||(a[x].tp=='Z'&&a[y].t==2)||(a[x].tp=='F'&&a[y].t==1))
\\x能否对y表敌意
#define youpig(x,y) (((a[x].tp=='M'||a[x].tp=='Z')&&a[y].t==1)||(a[x].tp=='F'&&a[y].t==2))
\\x能否对y献殷勤
\\y若未表明身份则都不能

Zhong jump, jump counter-very simple, if he used the "kill (K)", "Duel (F)", "impeccable (J)", it means that the identity, then the pig jump Zhong Zhong, anti-anti-pig jump. Here I put the main pig pig as a special kind of loyalty, a loyalty jump start.

Injury, death

As the pig will die, and they sat in a circle, so I used the list.

int nxt[15],las[15];//双向链表
void killed(int g,int p) {//g杀死了p
    if(a[p].tp=='M')end();//主猪死了,结束
    if(a[p].tp=='F') {
        if(!--f)end();//没有反猪了,结束
        a[g].mopai(3);//摸三张奖励牌
    } else if(a[p].tp=='Z'&&a[g].tp=='M')a[g].s=a[g].z=0;
    //主猪杀了忠猪,弃置所以牌和装备
    nxt[las[p]]=nxt[p];//从链表从删除p
    las[nxt[p]]=las[p];
}
void kouxue(int x,int y) {//以x为伤害来源,攻击y
    a[y].xue--;
    if(!a[y].xue)a[y].xue+=a[y].seach('P');//濒死,可以吃一个桃
    if(!a[y].xue)killed(x,y);//依然濒死,则y死亡
}

Impeccable

This is a special card, may be used recursively.

int wxkj(int s,int x) {//无懈可击成功返回1,否则返回0
    for(int i=s,f=0; !f||i!=s; i=nxt[i],f=1) {//从s开始
        if((!x?(dipig(i,s)):(youpig(i,x)))&&a[i].seach('J')) {
        //如果x不为0,说明s对x使用锦囊牌,否则说明s是上一次使用无懈可击
        //根据题意判断是否使用无懈可击
            a[i].t=a[i].tp=='F'?2:1;//i的身份明确
            return !wxkj(i,0);//递归使用无懈可击
        }
    }
    return 0;
}

The main operation

And finally to the main operations of the ~

    int now=1;//now为当前回合的猪
    a[1].t=1;//主猪一开始就跳忠
    if(!f)end();//一开始就没反猪
    while(1) {
        int kill=0;//是否使用过杀
        a[now].mopai(2);//摸2张牌
        for(int i=0; i<a[now].s&&a[now].xue; i++) {//枚举每张牌
            if(a[now].pai[i]=='Z') {//装备一定装备上,不管原来是否装备
                a[now].z=1,a[now].qizhi(i);
                i=-1;//可能之前杀可用,要从头枚举
            } else if(a[now].pai[i]=='P'&&a[now].xue<4) {//有桃一定吃
                a[now].xue++,a[now].qizhi(i);
            } else if(a[now].pai[i]=='K'&&(a[now].z||!kill)) {//能用杀
                int nx=nxt[now];//只能打下一个
                if(dipig(now,nx)) {//能表敌意
                    a[now].t=a[now].tp=='F'?2:1;//now身份明确
                    a[now].qizhi(i);
                    kill=1;
                    if(!a[nx].seach('D'))kouxue(now,nx);//nx没闪就扣血
                }
            } else if(a[now].pai[i]=='F') {//有决斗一定用
                for(int j=a[now].tp=='F'?1:nxt[now]; j!=now; j=nxt[j])
                //反猪一定与主猪决斗
                    if(dipig(now,j)) {
                        a[now].qizhi(i);
                        a[now].t=a[now].tp=='F'?2:1;//now身份明确
                        if(wxkj(now,j))break;//使用无懈可击
                        if(a[j].tp=='Z'&&a[now].tp=='M') {
                            kouxue(now,j);//主猪与忠猪决斗忠猪直接扣血
                            break;
                        }
                        int t=1;
                        while(1) {//决斗
                            if(t==1) {
                                if(!a[j].seach('K')) {
                                    kouxue(now,j);
                                    break;
                                }
                            } else if(!a[now].seach('K')) {
                                kouxue(j,now),i=max(-1,i-1);
                                break;
                            }
                            t^=1;
                        }
                        i=-1;
                        //决斗可能会导致一些猪使用无懈可击,明确身份,要从头开始枚举牌
                        break;
                    }
            } else if(a[now].pai[i]=='N'||a[now].pai[i]=='W') {
                //有南猪入侵和万箭齐发一定用
                char ch=a[now].pai[i];//保存是哪种
                a[now].qizhi(i);
                for(int j=nxt[now]; j!=now; j=nxt[j]) {//依次结算
                    if(!wxkj(now,j)&&!a[j].seach(ch=='N'?'K':'D')) {
                        if(a[j].tp=='M'&&!a[now].t)a[now].t=3;
                        //j是主猪,now未表明身份,则now为类反猪
                        kouxue(now,j);
                    }
                }
                i=-1;//同决斗,要从头开始枚举牌
            }
        }
        now=nxt[now];
    }

The complete code

Comment not playing

AC Code

#include<bits/stdc++.h>
using namespace std;
#define dipig(x,y) ((a[x].tp=='M'&&(a[y].t==2||a[y].t==3))||(a[x].tp=='Z'&&a[y].t==2)||(a[x].tp=='F'&&a[y].t==1))
#define youpig(x,y) (((a[x].tp=='M'||a[x].tp=='Z')&&a[y].t==1)||(a[x].tp=='F'&&a[y].t==2))
int nxt[15],las[15],top,f,n,m;
char tem[5],paidui[2010];
struct pig {
    char tp,pai[2010];
    int xue,s,z,t;
    void qizhi(int &x) {
        s--;
        for(int i=x; i<s; i++)
            pai[i]=pai[i+1];
        x--;
    }
    int seach(char ch) {
        for(int i=0; i<s; i++)
            if(pai[i]==ch) {
                qizhi(i);
                return 1;
            }
        return 0;
    }
    void mopai(int x) {
        for(int i=1; i<=x; i++) {
            pai[s++]=paidui[top++];
            if(top==m)top--;
        }
    }
} a[15];
void end() {
    puts(a[1].xue?"MP":"FP");
    for(int i=1; i<=n; i++) {
        if(a[i].xue==0)puts("DEAD");
        else {
            for(int j=0; j<a[i].s-1; j++)
                printf("%c ",a[i].pai[j]);
            if(a[i].s)printf("%c",a[i].pai[a[i].s-1]);
            puts("");
        }
    }
    exit(0);
}
void killed(int g,int p) {
    if(a[p].tp=='M')end();
    if(a[p].tp=='F') {
        if(!--f)end();
        a[g].mopai(3);
    } else if(a[p].tp=='Z'&&a[g].tp=='M')a[g].s=a[g].z=0;
    nxt[las[p]]=nxt[p];
    las[nxt[p]]=las[p];
}
void kouxue(int x,int y) {
    a[y].xue--;
    if(!a[y].xue)a[y].xue+=a[y].seach('P');
    if(!a[y].xue)killed(x,y);
}
int wxkj(int s,int x) {
    for(int i=s,f=0; !f||i!=s; i=nxt[i],f=1) {
        if((!x?(dipig(i,s)):(youpig(i,x)))&&a[i].seach('J')) {
            a[i].t=a[i].tp=='F'?2:1;
            return !wxkj(i,0);
        }
    }
    return 0;
}
int main() {
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++) {
        scanf("%s",tem);
        a[i].tp=tem[0];
        f+=tem[0]=='F';
        for(int j=0; j<4; j++)
            cin>>a[i].pai[j];
        nxt[i]=i+1,las[i]=i-1;
        a[i].s=a[i].xue=4;
    }
    for(int i=0; i<m; i++)cin>>paidui[i];
    nxt[n]=1,las[1]=n;
    int now=1;
    a[1].t=1;
    if(!f)end();
    while(1) {
        int kill=0;
        a[now].mopai(2);
        for(int i=0; i<a[now].s&&a[now].xue; i++) {
            if(a[now].pai[i]=='Z') {
                a[now].z=1,a[now].qizhi(i);
                i=-1;
            } else if(a[now].pai[i]=='P'&&a[now].xue<4) {
                a[now].xue++,a[now].qizhi(i);
            } else if(a[now].pai[i]=='K'&&(a[now].z||!kill)) {
                int nx=nxt[now];
                if(dipig(now,nx)) {
                    a[now].t=a[now].tp=='F'?2:1;
                    a[now].qizhi(i);
                    kill=1;
                    if(!a[nx].seach('D'))kouxue(now,nx);
                }
            } else if(a[now].pai[i]=='F') {
                for(int j=a[now].tp=='F'?1:nxt[now]; j!=now; j=nxt[j])
                    if(dipig(now,j)) {
                        a[now].qizhi(i);
                        a[now].t=a[now].tp=='F'?2:1;
                        if(wxkj(now,j))break;
                        if(a[j].tp=='Z'&&a[now].tp=='M') {
                            kouxue(now,j);
                            break;
                        }
                        int t=1;
                        while(1) {
                            if(t==1) {
                                if(!a[j].seach('K')) {
                                    kouxue(now,j);
                                    break;
                                }
                            } else if(!a[now].seach('K')) {
                                kouxue(j,now),i=max(-1,i-1);
                                break;
                            }
                            t^=1;
                        }
                        i=-1;
                        break;
                    }
            } else if(a[now].pai[i]=='N'||a[now].pai[i]=='W') {
                char ch=a[now].pai[i];
                a[now].qizhi(i);
                for(int j=nxt[now]; j!=now; j=nxt[j]) {
                    if(!wxkj(now,j)&&!a[j].seach(ch=='N'?'K':'D')) {
                        if(a[j].tp=='M'&&!a[now].t)a[now].t=3;
                        kouxue(now,j);
                    }
                }
                i=-1;
            }
        }
        now=nxt[now];
    }
    return 0;
}

Spectator mode

This code is output every step, every turn, there is agetchar

#include<bits/stdc++.h>
using namespace std;
#define dipig(x,y) ((a[x].tp=='M'&&(a[y].t==2||a[y].t==3))||(a[x].tp=='Z'&&a[y].t==2)||(a[x].tp=='F'&&a[y].t==1))
#define youpig(x,y) (((a[x].tp=='M'||a[x].tp=='Z')&&a[y].t==1)||(a[x].tp=='F'&&a[y].t==2))
int nxt[15],las[15],top,f,n,m;
char tem[5],paidui[2010];
struct pig {
    char tp,pai[2010];
    int xue,s,z,t;
    void qizhi(int &x) {
        s--;
        for(int i=x; i<s; i++)
            pai[i]=pai[i+1];
        x--;
    }
    int seach(char ch) {
        for(int i=0; i<s; i++)
            if(pai[i]==ch) {
                qizhi(i);
                return 1;
            }
        return 0;
    }
    void mopai(int x) {
        for(int i=1; i<=x; i++) {
            pai[s++]=paidui[top++];
            if(top==m)top--;
        }
    }
} a[15];
void end() {
    puts(a[1].xue?"MP":"FP");
    for(int i=1; i<=n; i++) {
        if(a[i].xue==0)puts("DEAD");
        else {
            for(int j=0; j<a[i].s-1; j++)
                printf("%c ",a[i].pai[j]);
            if(a[i].s)printf("%c",a[i].pai[a[i].s-1]);
            puts("");
        }
    }
    exit(0);
}
void killed(int g,int p) {
    if(a[p].tp=='M')end();
    if(a[p].tp=='F') {
        if(!--f)end();
        a[g].mopai(3);
    } else if(a[p].tp=='Z'&&a[g].tp=='M')a[g].s=a[g].z=0;
    nxt[las[p]]=nxt[p];
    las[nxt[p]]=las[p];
}
void kouxue(int x,int y) {
    a[y].xue--;
    if(!a[y].xue)
        if(a[y].seach('P'))a[y].xue++,cerr<<'P'<<' '<<y<<endl;
    if(!a[y].xue)killed(x,y);
}
int wxkj(int s,int x) {
    for(int i=s,f=0; !f||i!=s; i=nxt[i],f=1) {
        if((!x?(dipig(i,s)):(youpig(i,x)))&&a[i].seach('J')) {
            a[i].t=a[i].tp=='F'?2:1;
            cerr<<'J'<<' '<<i<<endl;
            return !wxkj(i,0);
        }
    }
    return 0;
}
int main() {
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++) {
        scanf("%s",tem);
        a[i].tp=tem[0];
        f+=tem[0]=='F';
        for(int j=0; j<4; j++)
            cin>>a[i].pai[j];
        nxt[i]=i+1,las[i]=i-1;
        a[i].s=a[i].xue=4;
    }
    for(int i=0; i<m; i++)cin>>paidui[i];
    nxt[n]=1,las[1]=n;
    int now=1;
    a[1].t=1;
    if(!f)end();
    while(1) {
        int kill=0;
        a[now].mopai(2);
        getchar();
        cerr<<now<<' '<<a[now].xue<<' '<<a[now].t<<' '<<a[now].z<<endl;
        for(int i=0; i<a[now].s; i++)cerr<<a[now].pai[i]<<' ';
        cerr<<endl;
        for(int i=0; i<a[now].s&&a[now].xue; i++) {
            if(a[now].pai[i]=='Z') {
                cerr<<'Z'<<endl;
                a[now].z=1,a[now].qizhi(i);
                i=-1;
            } else if(a[now].pai[i]=='P'&&a[now].xue<4) {
                cerr<<'P'<<endl;
                a[now].xue++,a[now].qizhi(i);
            } else if(a[now].pai[i]=='K'&&(a[now].z||!kill)) {
                int nx=nxt[now];
                if(dipig(now,nx)) {
                    cerr<<'K'<<' '<<nx<<endl;
                    a[now].t=a[now].tp=='F'?2:1;
                    a[now].qizhi(i);
                    kill=1;
                    if(!a[nx].seach('D'))kouxue(now,nx);
                    else cerr<<'D'<<endl;
                }
            } else if(a[now].pai[i]=='F') {
                for(int j=a[now].tp=='F'?1:nxt[now]; j!=now; j=nxt[j])
                    if(dipig(now,j)) {
                        cerr<<'F'<<' '<<j<<endl;
                        a[now].qizhi(i);
                        a[now].t=a[now].tp=='F'?2:1;
                        if(wxkj(now,j))break;
                        if(a[j].tp=='Z'&&a[now].tp=='M') {
                            kouxue(now,j);
                            break;
                        }
                        int t=1;
                        while(1) {
                            if(t==1) {
                                if(!a[j].seach('K')) {
                                    kouxue(now,j);
                                    break;
                                } else cerr<<'K'<<endl;
                            } else if(!a[now].seach('K')) {
                                kouxue(j,now),i=max(-1,i-1);
                                break;
                            } else cerr<<'K'<<endl;
                            t^=1;
                        }
                        i=-1;
                        break;
                    }
            } else if(a[now].pai[i]=='N'||a[now].pai[i]=='W') {
                char ch=a[now].pai[i];
                a[now].qizhi(i);
                cerr<<ch<<endl;
                for(int j=nxt[now]; j!=now; j=nxt[j]) {
                    if(wxkj(now,j))continue;
                    if(!a[j].seach(ch=='N'?'K':'D')) {
                        if(a[j].tp=='M'&&!a[now].t)a[now].t=3;
                        kouxue(now,j);
                    } else cerr<<(ch=='N'?'K':'D')<<endl;
                }
                i=-1;
            }
        }
        now=nxt[now];
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/hht2005/p/11526075.html