【求助】猪国杀求调,15pts,从7kb调到10kb了不行了
查看原帖
【求助】猪国杀求调,15pts,从7kb调到10kb了不行了
396974
Buried_Dream楼主2022/1/1 22:15

RT

/*
为了锻炼码力,2022第一道题是dmn 
work by: TLE_Automation
Time: O(TLE)
knowledge:
*/
#include<bits/stdc++.h>
#define TLE std
//#define orz cout << "Szt AK IOI!" << endl;
using namespace TLE;

inline int read() {
	int s = 0, w = 1;
	char ch = getchar();
	while (!isdigit(ch)) {if(ch == '-') {w = -1;}ch = getchar();}
	while (isdigit(ch)) {s = (s << 1) + (s << 3) + (ch ^ 48);ch = getchar();}
	return s * w;
}

inline void print(int x) {
	if (x < 0 ) putchar('-'), x = -x;
	if (x > 9 ) print(x / 10);
	putchar(x % 10 + '0');
}

const int N = 2e5 + 10;
const int MAX = 100;

struct node {
	int size, hp; // size 牌数, hp是血量,初始为4 
	char id, p[N];//id 是身份,p是他的手牌种类; 
	bool vis; //是否可以连杀 
	int nxt, lxt; // lxt 是 上一个打牌的, nxt 是下一个打牌的 
}pig[MAX]; 

//因为当反贼都死了主公和忠臣就赢了,所以记录反贼个数
//当主公死了反贼就赢了 
int Fz; //反贼个数
char ch[N]; //牌堆
char eye[MAX];// 主公认为他是什么猪,不知道是什么猪的统一认为是 A 
int n, m;string opt;char ch_1;
bool js = 0;

void clear(int x) { for(int i = 1; i <= 2001; i++) pig[x].p[i] = 'A'; }
void Get_card(int x) { 
	if(!m) {m++;}
 	pig[x].p[++pig[x].size] = ch[m];
	m--;
}
void Get_card2(int x) {Get_card(x), Get_card(x); }
void Get_card3(int x) { Get_card2(x), Get_card(x); }

void init() {
	n = read(), m = read();
	for(int i = 1; i <= n; i++) {
		clear(i); 
		pig[i].size = 4, pig[i].hp = 4, pig[i].vis = false;
		cin >> opt;
		if(opt == "MP") pig[i].id = 'M';
		else if(opt == "ZP") pig[i].id = 'Z';
		else if(opt == "FP") pig[i].id = 'F';		
		for(int j = 1; j <= 4; j++) cin >> pig[i].p[j]; // 一开始有4张手牌
	}
	for(int i = 1; i <= n; i++) {
		pig[i].nxt = i + 1, pig[i].lxt = i - 1; 
	} 
	//orz;
	pig[1].lxt = n, pig[n].nxt = 1; //形成一个环 
	eye[1] = 'M'; // 自己是主公 
	for(int i = 2; i <= n; i++) eye[i] = 'A';	// 剩下的人还不知道身份 
	for(int i = 1; i <= m; i++) cin >> ch_1, ch[m - i + 1] = ch_1;
	for(int i = 1; i <= n; i++) if(pig[i].id == 'F') Fz++;
} 

//-------------------------------以上函数没有问题------------------------------------// 

void check(int killer, int killeder) {
	if(killeder == 1) { js = 1;return; }	
	if(pig[killeder].id == 'F')  {
		Fz--;
		if(!Fz) {
		js = true;return; 
		}
	} 
	if(pig[killeder].id == 'F') {Get_card(killer);/*orz;*/Get_card(killer);Get_card(killer); }  // 给杀死反贼3张牌 
	
	if(pig[killeder].id == 'Z' && pig[killer].id  == 'M') { // 装备和手牌全弃了 
		pig[killer].size = 0, pig[killer].vis = false;
	}return; 
}

void dead(int killer, int killeder) {
	for(int i = 1; i <= pig[killeder].size; i++) {
		if(pig[killeder].p[i] == 'P') {	pig[killeder].p[i] = 'A', pig[killeder].hp++; }
	}
	pig[pig[killeder].nxt].lxt = pig[killeder].lxt;
	pig[pig[killeder].lxt].nxt = pig[killeder].nxt;
	check(killer, killeder);return;
}

void Kill(int killer, int killeder) {// 杀 
	for(int i = 1; i <= pig[killeder].size; i++) { //判断有没有闪 
		if(pig[killeder].p[i] == 'D') {	pig[killeder].p[i] = 'A'; return; }
	} pig[killeder].hp--;
	if(!pig[killeder].hp) { dead(killer, killeder); } 
}

bool Nofuction(int killer, int killeder, int pos) { // 无懈可击 
	int i = killer;
	while(true) {if(pos == 1) {
			if(eye[killeder] == pig[i].id || (eye[killeder] == 'M' && pig[i].id == 'Z') || (eye[killeder] == 'X' && pig[i].id == 'M'))  { 
				for(int j = 1; j <= pig[i].size; j++) {
					if(pig[i].p[j] == 'J') {
						pig[i].p[j] = 'A', eye[i] = pig[i].id; 
						  return !Nofuction(i, killer, 0);
					}	
				}				
			}
			else {
				if(((pig[i].id == 'M' || pig[i].id == 'Z' ) && eye[killer] == 'F') || 	(pig[i].id == 'F' && ( eye[killer] == 'M' || eye[killer] == 'Z'))) {
					for(int j = 1; j <= pig[i].size; j++) {
						if(pig[i].p[j] == 'J') {
							pig[i].p[j] = 'A', eye[i] = pig[i].id; 
							return !Nofuction(i, killer, 0);
						}
					}
				}
			}
			i = pig[i].nxt;
			if(i == killer) break;
		}
	}return false;
}

void invasion(int x) { // 南蛮入侵 
	for(int i = pig[x].nxt; i != x; i = pig[i].nxt) {
		if(Nofuction(x, i, 1)) continue; //无懈可击 
		for(int j = 1; j <= pig[i].size; j++) {
			if(pig[i].p[j] == 'K') { pig[i].p[j] = 'A'; return; }
		}pig[i].hp--;
	if(!pig[i].hp) dead(x, i); //x把i杀了 QAQ	 
	if(i == 1 && eye[x] == 'A') eye[x] = 'L';
	if(js) return;
	}	
}

void Arrow(int x) { //万箭齐发 
	for(int i = pig[x].nxt; i !=x ; i = pig[i].nxt ) {
		if(Nofuction(x, i , 1)) continue;
		for(int j = 1; j <= pig[i].size; j++) {
			if(pig[i].p[j] == 'D') {pig[i].p[j] = 'A';return;} 
		}pig[i].hp--;
	if(!pig[i].hp) dead(x, i);//x把i杀了 QAQ
	if(i == 1 && eye[x] == 'A') eye[x] = 'A';
	if(js) return;
	}	
} 

void Duel(int killer, int killeder) { // 决斗 
	if(Nofuction(killer, killeder, 1)) return;
	if(killer == 1 && pig[killeder].id == 'Z') {
		pig[killeder].hp--;
		if(!pig[killeder].hp) dead(killer, killeder);return;
	}while(true) { //有杀就嘎嘎使 
		int Sum = 1;
		while(pig[killeder].p[Sum] != 'K' && Sum <= pig[killeder].size) Sum++;
		if(Sum > pig[killeder].size) {
			pig[killeder].hp--;
			if(!pig[killeder].hp) dead(killer, killeder);
			return;
		}
		else pig[killeder].p[Sum] = 'A';
		int kil = 1;
		while(pig[killer].p[kil] != 'K' && kil <= pig[killer].size) kil++;
		if(kil > pig[killer].size) {
			pig[killer].hp--;
			if(!pig[killer].hp) dead(killeder, killer);
			return;
		}
		else pig[killer].p[kil] = 'A';
	}
	return;
}
  
int js1 = 0;
void star()
//进入回合 
{
	//要是没有反猪直接溜了,应该没这么sb的样例=_=
    if(!Fz) return;
    for(int i = 1; i; i = pig[i].nxt)
	{
        Get_card(i);
		Get_card(i);
        bool killed = true;
        for(int j = 1; j <= pig[i].size; j++)
        {
        	if(pig[i].p[j] == 'A') continue; 
        	if(!pig[i].hp) break;//就比如被决斗干死了 
            char crd = pig[i].p[j]; 
            //根据说明的优先级,先看【桃】 
            if(crd == 'P')//【桃】
			{
                if(pig[i].hp != 4)
                {
                	pig[i].hp++;
					pig[i].p[j] = 'A';
				}
                continue;
            }
            //接下来就看杀和闪了 
            if(crd == 'K')//【杀】 
			{
                if(!killed && !pig[i].vis) continue;//用过了,诸葛连弩没有装备 
                if(pig[i].id == 'Z'&&eye[pig[i].nxt] != 'F') continue;
					//忠猪不会主动打不是反的猪
				if(pig[i].id == 'F'&&eye[pig[i].nxt]!='Z'&&eye[pig[i].nxt]!='M') continue;
					//反猪不会主动打不是主猪眼中的忠主和主猪的猪
				if(pig[i].id=='M'&&eye[pig[i].nxt]!='L'&&eye[pig[i].nxt]!='F') continue;
					//主猪不会主动打不是类反猪和反猪的猪
                pig[i].p[j]='A';//没用了 
                Kill(i,pig[i].nxt);//开杀 
                eye[i]=pig[i].id;//暴露身份/jk 
				killed=false;
                if(js) return ;
                continue;
            }
            if(crd=='F')//【决斗】//有了杀就【决斗】吧(与题意无关,个人喜好)
			{
                if(pig[i].id=='F')//反猪显然干主猪 
				{
                    pig[i].p[j]='A';
					Duel(i,1);//干主猪 
                    eye[i]=pig[i].id;//暴露身份ok
                    if(js) return ;
                    j=0;//这里是尤其需要注意的,因为击杀之后可能会有摸卡牌,所以重置 
                    continue;
                }
                for(int k=pig[i].nxt;k!=i;k=pig[k].nxt)
                //主猪会去打已知的类反猪或者是反猪 
                	if((pig[i].id=='M' && (eye[k]=='L' || eye[k]=='F')) || 
						(pig[i].id=='Z' && eye[k]=='F'))
					{
                        pig[i].p[j]='A';
						Duel(i,k);
                        eye[i]=pig[i].id;
                    	if(js) return ;
                        j=0;
                        break;
                    }
                    continue;
            }
			if(crd=='Z')//【诸葛连弩】 
			{
                pig[i].vis=true;
                pig[i].p[j]='A';
                j=0;
                continue;
            }
            if(crd=='N') //【南蛮入侵】
			{
                pig[i].p[j]='A';
                invasion(i);
                if(js) 
					return;
                j=0;
                continue;
            }
            if(crd=='W') //【万箭齐发】 
			{
                pig[i].p[j]='A';
                Arrow(i);
                if(js) return ;
                j=0;
                continue;
            }
            
		}
    }
}
void start_() { //开始打牌 
	if(!Fz) return;
	//orz;
	for(int i = 1; i ; i = pig[i].nxt) { //从主公开始打牌 
		//js1++;//循环也没问题 
//		cout << i << endl;
		Get_card(i); //拿两张牌 
		//orz;
		Get_card(i);	
		bool killed = true; // 是否还能用杀 
		for(int j = 1; j <= pig[i].size; j++) {
			if(pig[i].p[j] == 'A') continue;  
			if(!pig[i].hp) break;
			if(pig[i].p[j] == 'P') { // 桃 
				if(pig[i].hp != 4) {
					pig[i].hp++;
					pig[i].p[j] == 'A';
				}
				continue; //因为一次只能出一张牌 
			} 
			if(pig[i].p[j] == 'K') { // 杀 
				if(!killed && pig[i].vis) continue;
				if(pig[i].id == 'Z' && eye[pig[i].nxt] != 'F') continue; // 不是反猪我不打
				if(pig[i].id == 'F' && eye[pig[i].nxt] != 'Z' && eye[pig[i].nxt] != 'M') continue;
				if(pig[i].id == 'M' && eye[pig[i].nxt] != 'F' && eye[pig[i].nxt] != 'L') continue;	
				pig[i].p[j] = 'A';
				Kill(i, pig[i].nxt);
				eye[i] = pig[i].id;
				killed = false;
				if(js) return;
				continue; 
			}
			if(pig[i].p[j] == 'F') { // 决斗 
				if(pig[i].id == 'F') {
					pig[i].p[j] = 'A', Duel(i, 1), eye[i] = 'F', j = 0;
					continue;
				}
				for(int k = pig[i].nxt; i != k; k = pig[k].nxt) {
					if(((pig[i].id == 'Z') && ( eye[k] == 'L' || eye[k] == 'L') ) || (pig[i].id == 'Z' && eye[k] == 'F')) { // 开干 
						pig[i].p[j] = 'A', Duel(i, k), eye[k] = pig[i].id;
						if(!js) return;
						j = 0;break;
					}
				}continue; 
			}
			if(pig[i].p[j] == 'Z') { // 诸葛连弩,可以乱杀! 
				pig[i].vis = true, pig[i].p[j] == 'A', j = 0;continue;  
			}
			if(pig[i].p[j] == 'N') { // 南蛮入侵 
				pig[i].p[j] = 'A';invasion(i); if(js) return; j = 0; continue;
			}
			if(pig[i].p[j] == 'W') { // 万箭齐发 
				pig[i].p[j] = 'A'; Arrow(i); if(js) return; j = 0; continue;
			} 
		}
	} 
}

signed main() {	
	init(); 
	//orz;
	/*for(int i = 1; i <= n; i++) {
		for(int j = i; j != pig[i].nxt; j = pig[j].nxt) {
			cout << j << endl;
		}
	}*/
//	cout << Fz << endl << endl; 
//-----------------------以上没有问题-------------------------------------------------------------------//	
//start_(); 
star();
//------------------------拿牌函数出现了问题,发现好像不止拿牌函数有问题艹-------------------------------//	
//	orz;
	if(pig[1].hp <= 0) puts("FP");
	else puts("MP"); 
	for(int i = 1; i <= n; i++) {
		if(pig[i].hp <= 0) puts("DEAD");
		else {
			for(int j = 1; j <= pig[i].size; j++) {
				if(pig[i].p[j] != 'A') cout << pig[i].p[j] << " ";
			}puts("");
		}
	}
	return 0;
}
2022/1/1 22:15
加载中...