[LOJ2885 / luoguP2482 / bzoj1972] 猪国杀

[LOJ2885 / luoguP2482 / bzoj1972] 猪国杀


大模拟,要注意一下数据貌似有问题,抽牌的时候没牌了就重复抽取最后一张、

然后貌似只有loj是完整的题面

然后就是各种读题&码

  • 先附上带调试信息的代码
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=20010;
char getch(){
	char x=0,res;while(x<'A'||x>'Z')x=getchar();
	res=x;while(x>='A'&&x<='Z')x=getchar();
	return res;
}
char x;
const int INF=998244353;
bool GAMEOVER=false;
char surfaceidentity[30];

//"functions
int n,m,cont;
bool if_enemy(int,int);
bool if_friend(int,int);
int find_enemy(int);
void playerdie(int);
void kill(int,int);
void invade(int);
void arrow(int);
void duel(int,int);
//"pre define

struct pig{
	char identity,equipment;
	int killtime,life,playerID,lplayer,rplayer;
	bool deadalready;
	struct handcard{
		int nxt,pre;
		char type;bool drewed;
	}card[N];
	int R,tot;
	//"functions below are a player's basic action including getting&drewing cards,doing terms etc.
	inline void getcard(){
		++cont;
		if(cont<=m)x=getch();
		card[++tot].type=x;
		card[tot].pre=R;
		//card[tot].nxt=0;
		card[R].nxt=tot;R=tot;
		//for(int i=1;i<=R;i++)cout<<card[i].nxt<<' ';
		//cout<<endl;
	}
	void drewcard(int x){
		card[x].drewed=true;
		//cout<<endl<<"drew!";
		//cout<<x<<' '<<card[x].drewed<<"|"<<identity;
		//cout<<"{}"<<card[1].drewed<<endl;
		card[card[x].pre].nxt=card[x].nxt;
		card[card[x].nxt].pre=card[x].pre;
		if(R==x)R=card[x].pre;
		//cout<<"ID:"<<playerID<<"  x"<<x<<'|'<<card[0].nxt<<endl<<endl;
	}
	inline int findcard(char x){
		//if(x=='D')cout<<playerID<<"finding D>>";
		//if(x=='D')cout<<card[0].nxt<<endl;
		int pos=card[0].nxt;
		while(pos) {
			if(card[pos].type==x)return pos;
			pos=card[pos].nxt;
		}
		return -1;
	}
	inline void MYTERM(){
		//cout<<"ID:"<<playerID<<endl;
		int pos=card[0].nxt;
		while(pos) {
			//print();
			//cout<<card[1].drewed<<endl;
			if(GAMEOVER||deadalready)return;
			//cout<<pos<<' '<<card[pos].drewed<<":"<<identity;
			if(card[pos].drewed==true){pos=card[pos].nxt;continue;}
			//"judge what to do
			//print();
			//cout<<pos<<"deciding on:"<<card[pos].type<<endl;
			if(decide(card[pos].type,pos))return;
			//cout<<card[pos].nxt<<endl;
			//cout<<pos<<endl;
			//for(int i=1;i<=R;i++)cout<<card[i].nxt<<' ';
			//cout<<endl;
			pos=card[pos].nxt;
		}
	}

	//"functions below are a player's reaction in different situations.
	inline void drewall(){
		equipment=0;
		killtime=0;
		int pos=card[0].nxt;
		while(pos) {
			//cout<<pos<<endl;
			drewcard(pos);
			pos=card[pos].nxt;
		}
		R=0;
	}
	inline void dead(pig &killer){
		//cout<<playerID<<' '<<life<<endl;
		int id=findcard('P');
		if(~id)life++,drewcard(id);
		else{
			playerdie(playerID);
			//cout<<killer.playerID<<"kill"<<playerID<<endl;
			if(GAMEOVER)return;
			if(identity=='Z'&&killer.identity=='M'){
				killer.drewall();
			}else if(identity=='F'){
				for(int i=1;i<=3;i++){
					killer.getcard();
				}
			}
		}
	}

	//"functions below are a player's dicision on giving cards
	inline bool decide(char cardtype,int id){
		if(cardtype=='P'){
			if(life<4){
			   	drewcard(id),life++;
				MYTERM();
				return true;
			}
		}else if(cardtype=='K'){
			int tar=-1;
			//cout<<playerID<<' '<<rplayer<<">>>";
			//cout<<if_enemy(playerID,rplayer)<<' '<<surfaceidentity[rplayer]<<endl;
			if(if_enemy(playerID,rplayer)){
				tar=rplayer;
				//cout<<"findtar:"<<tar<<endl;
			}
			if(~tar&&killtime>0){
				//cout<<"drewkill\n";
				drewcard(id);
				killtime--;
				kill(playerID,tar);
				MYTERM();
				return true;
			}
			return false;
		}else if(cardtype=='D'){
			return false;
		}else if(cardtype=='F'){
			if(identity=='F') { drewcard(id); duel(playerID,1); MYTERM(); return true;}
			int tar=find_enemy(playerID);
			if(~tar){
				drewcard(id);
				duel(playerID,tar);
				MYTERM();
				return true;
			}
			return false;
		}else if(cardtype=='N'){
			drewcard(id);
			invade(playerID);
			MYTERM();
			return true;
		}else if(cardtype=='W'){
			drewcard(id);
			arrow(playerID);
			MYTERM();
			return true;
		}else if(cardtype=='J'){
			return false;
		}else if(cardtype=='Z'){
			equipment='Z';
			killtime=INF;
			drewcard(id);
			MYTERM();
			return true;
		}
		return false;
	}
	//"printresult
	void print(){
		if(deadalready){
			printf("DEAD");
		}
		else{
			int pos=card[0].nxt;
			while(pos) {
				printf("%c ",card[pos].type);
				pos=card[pos].nxt;
			}
		}
		printf("\n");
	}
}player[30];
int Fcnt;
//"PLAY BOARD >>> here are functions to run the game by rules
void win(char side){
	printf("%cP\n",side);
	GAMEOVER=true;
}
void playerdie(int id){
//	cout<<id<<" is killed!!!!!"<<endl;
	player[id].deadalready=true;
	if(player[id].identity=='F')Fcnt--;
	player[player[id].rplayer].lplayer=player[id].lplayer;
	player[player[id].lplayer].rplayer=player[id].rplayer;
	if(Fcnt==0)win('M');
	if(player[id].identity=='M')win('F');
}

bool if_enemy(int u,int v){
	//cout<<u<<' '<<v<<endl;
	//cout<<player[u].identity<<' '<<surfaceidentity[v]<<' '<<player[v].identity<<endl;
	if(player[u].identity=='M')
		if(surfaceidentity[v]=='M'||surfaceidentity[v]=='F')return true;
	if(player[u].identity=='Z')
		if(surfaceidentity[v]=='F')return true;
	if(player[u].identity=='F')
		if(surfaceidentity[v]=='Z'||player[v].identity=='M')return true;
	return false;
}
bool if_friend(int u,int v){
	if(player[u].identity=='M')
		if(surfaceidentity[v]=='Z')return true;
	if(player[u].identity=='Z')
		if(surfaceidentity[v]=='Z'||player[v].identity=='M')return true;
	if(player[u].identity=='F')
		if(surfaceidentity[v]=='F')return true;
	return false;
}

inline int find_enemy(int ID){
	int pos=player[ID].rplayer;
	while(pos!=ID){
		if(if_enemy(ID,pos))return pos;
		pos=player[pos].rplayer;
	}
	return -1;
}

void kill(int u,int v){
	//cout<<u<<"is killing "<<v<<endl;
	
	int cardid=player[v].findcard('D');
	//cout<<cardid<<endl;
	if(~cardid){
		player[v].drewcard(cardid);
	}
	else player[v].life--;
	if(player[v].life<=0)player[v].dead(player[u]);
	if(u!=1)surfaceidentity[u]=player[u].identity;
}

bool cancleopt(int ID,int former,bool ifharm){
	//cout<<ID<<' '<<former<<' '<<ifharm<<endl;
	int pos=former;
	bool res=false;
	while(true){
		if(GAMEOVER)return true;
		//if(cancleopt(pos,former,1))continue;
		if(!(ifharm&&if_friend(pos,ID)) && !(!ifharm&&if_enemy(pos,ID))){
			pos=player[pos].rplayer;
			if(pos==former)break;
			continue;
		}//"should not play
		int cardid=player[pos].findcard('J');
		if(~cardid){
			
			//cout<<pos<<"drew his DEFENCE to" << ID <<endl;
			
			if(pos!=1)surfaceidentity[pos]=player[pos].identity;
			
			player[pos].drewcard(cardid);
			res=true;
			if(cancleopt(ID,pos,ifharm^1))res=false;
			break;
		}
		pos=player[pos].rplayer;
		if(pos==former)break;
	}
	return res;
}

void invade(int ID){
	int pos=player[ID].rplayer;

	//cout<<"INVADING"<<'|'<<"starter :"<<ID<<endl;
	//player[1].print();
	//cout<<endl;

	while(pos!=ID){
		if(GAMEOVER)return;
		//cout<<"judge on pos"<<pos<<endl;
		if(cancleopt(pos,ID,1)){pos=player[pos].rplayer;continue;}
		int cardid=player[pos].findcard('K');
		if(~cardid)
			player[pos].drewcard(cardid);
		else {
			player[pos].life--;
			
			//cout<<pos<<' '<<"damaged"<<endl;
			
			if(player[pos].identity=='M')if(surfaceidentity[ID]!=player[ID].identity)surfaceidentity[ID]='M';
			if(player[pos].life<=0)player[pos].dead(player[ID]);
		}
		pos=player[pos].rplayer;
	}
}

void arrow(int ID){
	int pos=player[ID].rplayer;
	
	//cout<<"ARROWING"<<'|'<<"starter : "<<ID<<endl;
	
	while(pos!=ID){
		//cout<<pos<<' '<<GAMEOVER<<endl;
		if(GAMEOVER)return;
		if(cancleopt(pos,ID,1)){pos=player[pos].rplayer;continue;}
		int cardid=player[pos].findcard('D');
		if(~cardid)
			player[pos].drewcard(cardid);
		else {
			player[pos].life--;
			
			//cout<<pos<<' '<<"damaged"<<endl;
			
			if(player[pos].identity=='M')if(surfaceidentity[ID]!=player[ID].identity)surfaceidentity[ID]='M';
			if(player[pos].life<=0)player[pos].dead(player[ID]);
		}
		pos=player[pos].rplayer;
	}
}

void duel(int ID1,int ID2){
	
	//cout<<"HAVING A DUEL WITH "<<ID1<<'&'<<ID2<<endl;
	
	if(ID1!=1)surfaceidentity[ID1]=player[ID1].identity;
	if(cancleopt(ID2,ID1,1))return;
	if(player[ID2].identity=='Z'&&player[ID1].identity=='M'){
		player[ID2].life--;
		if(player[ID2].life<=0)player[ID2].dead(player[ID1]);
		return;
	}
	int atk=ID1,dfn=ID2;
	while(true){
		swap(atk,dfn);
		int cardid=player[atk].findcard('K');
		if(~cardid){
			player[atk].drewcard(cardid);
		}else {
			break;
		}
	}
	//cout<<atk<<"lose!"<<endl;
	player[atk].life--;
	if(player[atk].life<=0)player[atk].dead(player[dfn]);
}

inline void playing(){
	int pos=1;
	while(!GAMEOVER){
		player[pos].getcard();player[pos].getcard();
		//cout<<pos<<">>"<<player[pos].identity<<endl;
		//player[pos].print();
		//cout<<"having his term..."<<endl;

		player[pos].killtime=player[pos].equipment=='Z'?INF:1;
		player[pos].MYTERM();
		
		//for(int i=1;i<=n;i++)cout<<">>>"<<player[i].identity<<" "<<surfaceidentity[i]<<' '<<player[i].life<<endl;
		//cout<<pos<<">>"<<player[pos].identity<<endl;
		//player[pos].print();
		
		pos=player[pos].rplayer;
	}
}

inline void init(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		player[i].playerID=i;
		player[i].life=4;
		player[i].lplayer=i-1,player[i].rplayer=i+1;
		player[i].identity=getch();
		//cout<<player[i].identity<<endl;
		if(player[i].identity=='F')Fcnt++;
		for(int p=1;p<=4;p++){cont=0;player[i].getcard();}
	}
	player[1].lplayer=n,player[n].rplayer=1;
	surfaceidentity[1]='Z';
}

int main()
{
	init();
	cont=0;
	playing();
	for(int i=1;i<=n;i++){
		player[i].print();
	}
}
  • 以下是各种 压行 加 魔改之后的代码
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=20010;
char getch(){
    char x=0,res;while(x<'A'||x>'Z')x=getchar();
    res=x;while(x>='A'&&x<='Z')x=getchar();
    return res;
}
char x;
const int INF=998244353;
bool GAMEOVER=false;
char surfaceidentity[30];
int n,m,cont;
//"functions
bool if_enemy(int,int);
bool if_friend(int,int);
int find_enemy(int);
void playerdie(int);
void kill(int,int);
void invade(int);
void arrow(int);
void duel(int,int);
//"pre define

struct pig{
    //"informations
    char identity,equipment;
    int killtime,life,playerID,lplayer,rplayer;
    bool deadalready;
    struct handcard{
        int nxt,pre;
        char type;bool drewed;
    }card[N];
    int R,tot;
    //"functions below are a player's basic action including getting&drewing cards,doing terms etc.
    inline void getcard(){
        ++cont;
        if(cont<=m)x=getch();
        card[++tot].type=x; card[tot].pre=R;
        card[R].nxt=tot; R=tot;
    }
    void drewcard(int x){
        card[x].drewed=true;
        card[card[x].pre].nxt=card[x].nxt; card[card[x].nxt].pre=card[x].pre;
        if(R==x) R=card[x].pre;
    }
    inline int findcard(char x){
        int pos=card[0].nxt;
        while(pos) {
            if(card[pos].type==x)return pos;
            pos=card[pos].nxt;
        }
        return -1;
    }
    inline void MYTERM(){
        int pos=card[0].nxt;
        while(pos) {
            if(GAMEOVER||deadalready)return;
            if(card[pos].drewed==true){pos=card[pos].nxt;continue;}
            //"judge what to do
            if(decide(card[pos].type,pos))return;
            pos=card[pos].nxt;
        }
    }
    //"functions below are a player's reaction in different situations.
    inline void drewall(){
        equipment=0,killtime=0;
        int pos=card[0].nxt;
        while(pos) {
            drewcard(pos);
            pos=card[pos].nxt;
        }
        R=0;
    }
    inline void dead(pig &killer){
        int id=findcard('P');
        if(~id)life++,drewcard(id);
        else{
            playerdie(playerID);
            if(GAMEOVER)return;
            if(identity=='Z'&&killer.identity=='M')
                killer.drewall();
            else if(identity=='F')
                for(int i=1;i<=3;i++)
                    killer.getcard();
        }
    }
    //"functions below are a player's dicision on giving cards
    inline bool decide(char cardtype,int id){
        if(cardtype=='P'){
            if(life<4){
                drewcard(id),life++;
                MYTERM();
                return true;
            }
        }else if(cardtype=='K'){
            int tar=-1;
            if(if_enemy(playerID,rplayer)) tar=rplayer;
            if(~tar&&killtime>0){
                drewcard(id);
                killtime--;
                kill(playerID,tar);
                MYTERM();
                return true;
            }
            return false;
        }else if(cardtype=='D'){
            return false;
        }else if(cardtype=='F'){
            if(identity=='F') { drewcard(id); duel(playerID,1); MYTERM(); return true;}
            int tar=find_enemy(playerID);
            if(~tar){
                drewcard(id);
                duel(playerID,tar);
                MYTERM();
                return true;
            }
            return false;
        }else if(cardtype=='N'){
            drewcard(id);
            invade(playerID);
            MYTERM();
            return true;
        }else if(cardtype=='W'){
            drewcard(id);
            arrow(playerID);
            MYTERM();
            return true;
        }else if(cardtype=='J'){
            return false;
        }else if(cardtype=='Z'){
            equipment='Z';
            killtime=INF;
            drewcard(id);
            MYTERM();
            return true;
        }
        return false;
    }
    //"printresult
    void print(){
        if(deadalready)
            printf("DEAD");
        else{
            int pos=card[0].nxt;
            while(pos) {
                printf("%c ",card[pos].type);
                pos=card[pos].nxt;
            }
        }
        printf("\n");
    }

}player[30];

//"PLAY BOARD >>> here are functions to run the game by rules

int Fcnt;
void win(char side){
    printf("%cP\n",side);
    GAMEOVER=true;
}
void playerdie(int id){
    player[id].deadalready=true;
    if(player[id].identity=='F')Fcnt--;
    player[player[id].rplayer].lplayer=player[id].lplayer;
    player[player[id].lplayer].rplayer=player[id].rplayer;
    if(Fcnt==0)win('M');
    if(player[id].identity=='M')win('F');
}
//"judge the relationship
bool if_enemy(int u,int v){
    if(player[u].identity=='M')
        if(surfaceidentity[v]=='M'||surfaceidentity[v]=='F')return true;
    if(player[u].identity=='Z')
        if(surfaceidentity[v]=='F')return true;
    if(player[u].identity=='F')
        if(surfaceidentity[v]=='Z'||player[v].identity=='M')return true;
    return false;
}
bool if_friend(int u,int v){
    if(player[u].identity=='M')
        if(surfaceidentity[v]=='Z')return true;
    if(player[u].identity=='Z')
        if(surfaceidentity[v]=='Z'||player[v].identity=='M')return true;
    if(player[u].identity=='F')
        if(surfaceidentity[v]=='F')return true;
    return false;
}
inline int find_enemy(int ID){
    int pos=player[ID].rplayer;
    while(pos!=ID){
        if(if_enemy(ID,pos))return pos;
        pos=player[pos].rplayer;
    }
    return -1;
}
//"cards
void kill(int u,int v){
    int cardid=player[v].findcard('D');
    if(~cardid){
        player[v].drewcard(cardid);
    }
    else player[v].life--;
    if(player[v].life<=0)player[v].dead(player[u]);
    if(u!=1)surfaceidentity[u]=player[u].identity;
}

bool cancleopt(int ID,int former,bool ifharm){
    int pos=former;
    bool res=false;
    while(true){
        if(GAMEOVER)return true;
        if(!(ifharm&&if_friend(pos,ID)) && !(!ifharm&&if_enemy(pos,ID))){
            pos=player[pos].rplayer;
            if(pos==former)break;
            continue;
        }//"should not play
        int cardid=player[pos].findcard('J');
        if(~cardid){
            if(pos!=1)surfaceidentity[pos]=player[pos].identity;
            player[pos].drewcard(cardid);
            res=true;
            if(cancleopt(ID,pos,ifharm^1))res=false;
            break;
        }
        pos=player[pos].rplayer;
        if(pos==former)break;
    }
    return res;
}

void invade(int ID){
    int pos=player[ID].rplayer;
    while(pos!=ID){
        if(GAMEOVER)return;
        if(cancleopt(pos,ID,1)){pos=player[pos].rplayer;continue;}
        int cardid=player[pos].findcard('K');
        if(~cardid)
            player[pos].drewcard(cardid);
        else {
            player[pos].life--;
            if(player[pos].identity=='M')if(surfaceidentity[ID]!=player[ID].identity)surfaceidentity[ID]='M';
            if(player[pos].life<=0)player[pos].dead(player[ID]);
        }
        pos=player[pos].rplayer;
    }
}

void arrow(int ID){
    int pos=player[ID].rplayer;
    while(pos!=ID){
        if(GAMEOVER)return;
        if(cancleopt(pos,ID,1)){pos=player[pos].rplayer;continue;}
        int cardid=player[pos].findcard('D');
        if(~cardid)
            player[pos].drewcard(cardid);
        else {
            player[pos].life--;
            if(player[pos].identity=='M')if(surfaceidentity[ID]!=player[ID].identity)surfaceidentity[ID]='M';
            if(player[pos].life<=0)player[pos].dead(player[ID]);
        }
        pos=player[pos].rplayer;
    }
}

void duel(int ID1,int ID2){
    if(ID1!=1)surfaceidentity[ID1]=player[ID1].identity;
    if(cancleopt(ID2,ID1,1))return;
    if(player[ID2].identity=='Z'&&player[ID1].identity=='M'){
        player[ID2].life--;
        if(player[ID2].life<=0)player[ID2].dead(player[ID1]);
        return;
    }
    int atk=ID1,dfn=ID2;
    while(true){
        swap(atk,dfn);
        int cardid=player[atk].findcard('K');
        if(~cardid)
            player[atk].drewcard(cardid);
        else break;
    }
    player[atk].life--;
    if(player[atk].life<=0)player[atk].dead(player[dfn]);
}
//"main
inline void playing(){
    int pos=1;
    while(!GAMEOVER){
        player[pos].getcard();player[pos].getcard();
        player[pos].killtime=player[pos].equipment=='Z'?INF:1;
        player[pos].MYTERM();
        pos=player[pos].rplayer;
    }
}

inline void init(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        player[i].playerID=i;
        player[i].life=4;
        player[i].lplayer=i-1,player[i].rplayer=i+1;
        player[i].identity=getch();
        if(player[i].identity=='F')Fcnt++;
        for(int p=1;p<=4;p++){cont=0;player[i].getcard();}
    }
    player[1].lplayer=n,player[n].rplayer=1;
    surfaceidentity[1]='Z';
}

int main()
{
    init();cont=0;
    playing();
    for(int i=1;i<=n;i++) player[i].print();
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值