关于一些小错误和供大家调试的代码
查看原帖
关于一些小错误和供大家调试的代码
251449
hfjh楼主2023/11/5 19:28

有几个容易错的地方提醒大家:

1.主公和忠臣决斗忠臣不能出杀

2.有可能某一次出的牌影响到跳反/跳忠,之前本来不能出的现在可以出了,要重新判一下。(例如某只反猪出了个南蛮入侵,他的下一位为主猪出了无懈可击,跳忠了,之前这只猪手牌有一张杀在南蛮入侵之前,但因为没有目标被跳过了,现在要重新用)

最后给一份带调试的代码供大家使用(题解区第三页 Ice_teapoy 大佬的调试也很详细,大家也可以看看他的):

#include<bits/stdc++.h>
#define puba push_back
using namespace std;
const char a[9] = {' ', 'P', 'K', 'D', 'F', 'N', 'W', 'J', 'Z'};
map<char, int>b;
int n, nn, m, num, siz[2], mp;
char w;
int fwj[2010];
int ned, who, where;
string name;
struct node{
	int lf;
	int nxt, las, t[10], id1, id2;
	int z;
	int vis;
	vector<int>p;
}x[11];
stack<int>s;
void input(){
	cin >> n >> m;
	for(int i = 1; i <= n; ++i){
		cin >> name; 
		x[i].lf = 4;
		if(name == "MP") x[i].id1 = 1, x[i].id2 = 2, ++siz[0], mp = i;
		if(name == "ZP") x[i].id1 = 2;
		if(name == "FP") x[i].id1 = 3, ++siz[1];
		for(int j = 1; j <= 4; ++j){
			cin >> w; num = b[w];
			x[i].p.puba(num); ++x[i].t[num];
		}
		x[i].nxt = i + 1;
		x[i].las = i - 1;
		if(i == 1) x[i].las = n; 
		if(i == n) x[i].nxt = 1;
	}
	for(int i = 1; i <= m; ++i){
		cin >> w;
		fwj[i] = b[w];
	}
	for(int i = m; i >= 1; --i) s.push(fwj[i]);
}
bool ck_rl(int a, int b){
	if(x[a].id1 == 1 && (x[b].id2 == 3 || x[b].id2 == 4)){
		return 1;
	}
	if(x[a].id1 == 2 && x[b].id2 == 3){
		x[a].id2 = 2;
		cerr<<a<<"变成好人\n"; 
		return 1;
	}
	if(x[a].id1 == 3 && (x[b].id2 == 1 || x[b].id2 == 2)){
		x[a].id2 = 3;
		cerr<<a<<"变成坏人\n"; 
		return 1;
	}
	return 0;
}
bool delet(int o, int ty, int w){
	if(x[o].t[ty]){
		cerr<<o<<"有"<<ty<<"这张牌,用掉\n"; 
		--x[o].t[ty];
		if(w != -1){
			x[o].p.erase(x[o].p.begin() + w);
			if(who == o && w <= where) --where; 
		}else{
			for(int i = 0; i < x[o].p.size(); ++i){
				if(x[o].p[i] == ty){
					x[o].p.erase(x[o].p.begin() + i);
					if(who == o && i <= where) --where; 
					break;	
				}
			}
		}
		return 1;
	}
	return 0;
} 
bool ck_lf(int o){
	if(x[o].lf == 0){
		if(!delet(o, 1, -1)){
			cerr<<"没有桃,"<<o<<"死了\n";
			x[x[o].las].nxt = x[o].nxt;
			x[x[o].nxt].las = x[o].las;
			--nn; x[o].vis = 1;
			if(x[o].id1 == 3) --siz[1];
			if(x[o].id1 == 1) --siz[0];
			return 1;
		}else{
			cerr<<o<<"有桃,不死\n";
			++x[o].lf;
		}
	}
	return 0;
}
void ck_ws(int a, int b){
	if(x[a].id1 == 1 && x[b].id1 == 2){
		cerr<<"主公"<<a<<"把忠臣"<<b<<"误杀了,清空手牌\n";
		for(int i = 1; i <= 8; ++i) x[a].t[i] = 0;
		x[a].z = 0; x[a].p.clear(); 
	}
	
}
void ck_zs(int a, int b){
	if(x[b].id1 == 3){
		x[a].p.puba(s.top()), x[a].t[s.top()]++; if(s.size() > 1) s.pop();
		x[a].p.puba(s.top()), x[a].t[s.top()]++; if(s.size() > 1) s.pop();
		x[a].p.puba(s.top()), x[a].t[s.top()]++; if(s.size() > 1) s.pop();
	}
}
bool ck_end(){
	cerr<<"剩余人数"<<siz[0]<<' '<<siz[1]<<' '<<!(siz[0] && siz[1])<<"\n";
	return !(siz[0] && siz[1]); 
}
bool query(int o, int ty){
	int j = o, ans1 = 0, ans2 = 0;
	do{
//		cerr<<j<<' '<<o<<' '<<"fuck\n";
		if((x[j].id2 == ty || x[j].id1 == ty) && delet(j, 7, -1)){
			x[j].id2 = ty; ans1 = 1;
			cerr<<j<<"使用无懈可击,他变成了"<<((ty == 3) ? "坏" : "好")<<"人。\n"; 
			if(ty == 2) ans2 = query(j, 3);
			else if(ty == 3) ans2 = query(j, 2);
			break;
		}
		j = x[j].nxt;
	}while(j != o);
	if(ans1 ^ ans2) cerr<<j<<"的无懈可击有效\n";
	else if(ans1) cerr<<j<<"的无懈可击无效\n";
	return ans1 ^ ans2;
} 
int pre(int o){
	if(x[o].id1 == 1 || x[o].id1 == 2) return 2;
	if(x[o].id1 == 3) return 3;
}
void print(){
	for(int i = 1; i <= n; ++i){
		cerr<<i<<":\n";
		cerr<<"血量"<<x[i].lf<<"\n"; 
		cerr<<"状态"<<x[i].id2<<'\n';
		if(x[i].vis) cerr<<"DEAD";
		else{
			for(auto j : x[i].p){
				cerr<<j<<' ';
			}
		}
		cerr<<'\n';
	}
}
void op(){
	int o = 1, killed = 0;
	while(siz[0] && siz[1]){
		x[o].p.puba(s.top()), x[o].t[s.top()]++; if(s.size() > 1) s.pop();
		x[o].p.puba(s.top()), x[o].t[s.top()]++; if(s.size() > 1) s.pop();
		killed = 0;
		int i = 0;
		who = o;
		while(i < x[o].p.size()){
			where = i;
			cerr<<o<<"人的"<<i + 1<<"张牌"<<x[o].p[i]<<"\n";
			if(x[o].p[i] == 1){ //桃 
				if(x[o].lf < 4){
					cerr<<o<<"使用一张桃\n"; 
					++x[o].lf;
					delet(o, 1, i); i = where;
				}
			}else
			if(x[o].p[i] == 2){//杀 
				if(ck_rl(o, x[o].nxt) && ( (!killed) || x[o].z)){
					cerr<<o<<"对"<<x[o].nxt<<"使用一张杀\n"; 
					delet(o, 2, i); i = where;
					if(!delet(x[o].nxt, 3, -1)){
						i = where;
						cerr<<x[o].nxt<<"没有闪,扣血\n"; 
						--x[x[o].nxt].lf; int zs = x[o].nxt;
						if(ck_lf(x[o].nxt)){
							if(ck_end()) break;
							ck_ws(o, zs);
							ck_zs(o, zs);						
						}
					}else{
						cerr<<x[o].nxt<<"有闪\n"; 
					}
					killed = 1;
					if(ck_end()) break;
				}
			}else
			if(x[o].p[i] == 4){//决斗 
				int used = 0;
				for(int j = x[o].nxt; j != o; j = x[j].nxt){
					if(x[o].id1 == 3 && x[j].id1 != 1) continue; 
//					cerr<<"a"<<i<<' '<<j<<'\n';
					
				 	if(ck_rl(o, j)){
				 		cerr<<o<<"对"<<j<<"使用一张决斗\n"; 
						delet(o, 4, i); i = where;
					 	if(x[j].id2 != 0 && x[j].id2 != 4 && query(o, pre(j)) ){
					 		cerr<<j<<"被保护\n"; 
							break;	
						}	
				 		cerr<<"开始决斗\n"; 
						
				 		cerr<<"杀的个数分别为:"<<x[o].t[2]<<' '<<x[j].t[2]<<'\n';
						 if(x[o].t[2] >= x[j].t[2] || (x[o].id1 == 1 && x[j].id1 == 2)){
							--x[j].lf;
							cerr<<j<<"扣血\n"; 
							for(int k = 1; k <= x[j].t[2]; ++k){
								delet(o, 2, -1); delet(j, 2, -1);
							}
							i = where;
							if(ck_lf(j)){
								if(ck_end()) break;
								ck_ws(o, j);
								ck_zs(o, j);						
							}
						}else{
							--x[o].lf; 
							cerr<<o<<"扣血\n"; 
							for(int k = 1; k <= x[o].t[2]; ++k){
								delet(o, 2, -1); delet(j, 2, -1);
							}
							delet(j, 2, -1);
							i = where;
							if(ck_lf(o)){
								if(ck_end()) break;
								ck_ws(j, o);
								ck_zs(j, o);	
								break;	
							}
							
						}
						where = i = -1; 
						break;
					}
				}
				if(x[o].vis) break;
				if(ck_end()) break;
			}else
			if(x[o].p[i] == 5 || x[o].p[i] == 6){//南蛮/万箭 
				int g = x[o].p[i] - 3;
				if(x[o].p[i] == 5) cerr<<o<<"使用南蛮入侵\n"; 
				if(x[o].p[i] == 6) cerr<<o<<"使用万箭齐发\n"; 
				delet(o, x[o].p[i], i); i = where;
				for(int j = x[o].nxt; j != o; j = x[j].nxt){
					if(x[j].id2 != 0 && x[j].id2 != 4 && query(o, pre(j))){
						cerr<<j<<"被保护\n";
						continue;
					}
					if(!delet(j, g, -1)){ 
						
						--x[j].lf;
						cerr<<j<<"扣血\n"; 
						if(ck_lf(j)){
							if(ck_end()) break;
							ck_ws(o, j);
							ck_zs(o, j);						
						}
						if(x[j].id1 == 1 && x[o].id2 == 0){
							cerr<<o<<"被标记为类反猪\n";
							x[o].id2 = 4;
						}
					}else{
						if(g == 2) cerr<<j<<"有杀\n";
						if(g == 3) cerr<<j<<"有闪\n";
					} 
				}
				where = i = -1; 
				if(ck_end()) break;
			}else
			if(x[o].p[i] == 8){
				cerr<<o<<"装备诸葛连弩\n";
				x[o].z = 1;
				delet(o, 8, i);i = where;
				i = where = -1;
				if(ck_end()) break;
			}
			i = where;
			cerr<<i<<" "<<x[o].p.size();
			++i; 
			if(ck_end()) break;
		}
		if(ck_end()) break;
		
		print();
		o = x[o].nxt;
	}
}
void output(){
	if(siz[0] == 0) cout<<"FP\n";
	if(siz[1] == 0) cout<<"MP\n";
	for(int i = 1; i <= n; ++i){
		if(x[i].vis) cout<<"DEAD";
		else{
			for(auto j : x[i].p){
				cout<<a[j]<<' ';
			}
		}
		cout<<'\n';
	}
}
int main(){
//	freopen("1.in","r",stdin);
//	freopen("1.out","w",stdout);
	for(int i = 1; i <= 8; ++i) b[a[i]] = i;
	input();
	for(int i = 1; i <= n; ++i){
		cerr<<i<<":\n";
		cerr<<"血量"<<x[i].lf<<"\n"; 
		cerr<<"状态"<<x[i].id2<<'\n';
		if(x[i].vis) cerr<<"DEAD";
		else{
			for(auto j : x[i].p){
				cerr<<j<<' ';
			}
		}
		cerr<<'\n';
	}
	op();
	output();
}

2023/11/5 19:28
加载中...