下载测试点能过但是提交后 RE
查看原帖
下载测试点能过但是提交后 RE
844860
CommandSR楼主2025/1/27 22:21

rt,下载#1本地能过但是提交后 RE

输入全用的 cin

#include <bits/stdc++.h>
using namespace std;
const int N = 15, M = 2010;
int n, m, cur;
char card[M]; // 总牌堆
int cpos = 1; // 牌堆顶编号
struct player {
	string typ; // 角色
	char C[M]; // 手牌
	int cc; // 手牌数 (该变量只加不减,手牌能不能用看 vis 数组)
	int hp, last; // 血量,最后一个伤害来源
	bool weap; // 有没有装猪哥连弩
} a[N];
bool vis[N][M]; // 每一位玩家的每一张手牌有没有用
bool jump[N]; // 玩家 i 是否跳身份
bool likefp[N]; // 在主猪看来是不是类反猪
void throw_card(int p, int pos) { // 玩家 p 丢弃 下标为 pos 的卡牌
	vis[p][pos] = 1;
}
bool same_camp(int p, int i) { // 判断 p 和 i 是否属于同一阵营
	return (((a[p].typ == "MP" || a[p].typ == "ZP") && (a[i].typ == "MP" || a[i].typ == "ZP")) || (a[i].typ == "FP" && a[p].typ == "FP"));
}
void game_result(string res) { // 游戏结束后结算输出
	cout << res << '\n';
	for (int i = 1; i <= n; i++) {
		if (a[i].hp <= 0) {
			cout << "DEAD\n";
			continue ;
		}
		for (int j = 1; j <= a[i].cc; j++) {
			if (vis[i][j]) continue ;
			cout << a[i].C[j] << ' ';
		}
		cout << '\n';
	}
	exit(0);
}
void check_game_over() {
	bool ff = 1, fz = 1, fm = 1; // 反,主,忠猪有没有都死
	for (int p = 1; p <= n; p++) {
		//		cout << a[p].typ << ' ' << a[p].hp << ' ' << a[p].C[a[p].cc] << ' ';
		if (a[p].typ == "MP" && a[p].hp > 0) fm = 0;
		else if (a[p].typ == "ZP" && a[p].hp > 0) fz = 0;
		else if (a[p].typ == "FP" && a[p].hp > 0) ff = 0;
	}
	//	cout << '\n';
	if (fm) game_result("FP");
	else if (ff) game_result("MP");
	return ;
}
void get_cards(int p, int num) { // 摸牌
	for (int i = 1; i <= num; i++) {
		if (cpos > m) a[p].C[++a[p].cc] = card[m];
		else a[p].C[++a[p].cc] = card[cpos++];
	}
}
int find_card(int p, char ch) { // 在玩家 p 牌堆里找 卡牌 ch ,若没有,返回 -1
	for (int i = 1; i <= a[p].cc; i++) {
		if (vis[p][i]) continue ;
		if (a[p].C[i] == ch) return i;
	}
	return -1;
}
void dead_result(int p, int q) { // 玩家 p 被玩家 q 击杀,结算
	int pt = find_card(p, 'P');
	if (pt != -1) {
		throw_card(p, pt);
		a[p].hp ++;
		if (a[p].hp > 0) return ;
	}
	if (a[p].typ == "MP") game_result("FP");
	else if (a[p].typ == "FP") get_cards(q, 3);
	else if (a[p].typ == "ZP" && a[q].typ == "MP") {
		for (int i = 1; i <= a[q].cc; i++) vis[q][i] = 1;
		a[q].weap = 0;
	}
	
}
int find_enm_tag(int p) { // 玩家 p 寻找表敌意的目标,如果没有返回 -1
	int i = p + 1;
	while (1) {
		if (i > n) i = 1;
		if (i == p) return -1; // 找了一圈没有目标
		if (a[i].hp > 0) {
			if (a[p].typ == "MP")
				if ((jump[i] && a[i].typ == "FP") || (!jump[i] && likefp[i])) return i;
			else if (a[p].typ == "ZP")
				if (jump[i] && a[i].typ == "FP") return i;
			else if (a[p].typ == "FP") if (a[i].typ == "MP") return i;
		}	
		i ++;	
	}
}
void aoe_attack(int p, char ch) { // 玩家 p 发动 南猪入侵 或 万箭齐发,要求其余玩家丢弃一张 ch
	for (int i = 1; i <= n; i++) {
		if (a[i].hp <= 0 || i == p) continue ;
		if (jump[p] && same_camp(p, i)) {
			int pw = find_card(i, 'J');
			if (pw != -1) {
				jump[i] = 1;
				throw_card(i, pw);
				continue ;
			}
		}
		int pi = find_card(i, ch);
		if (pi == -1) {
			a[i].hp --;
			if (!jump[p] && a[i].typ == "MP") likefp[p] = 1;
		}
		if (a[i].hp <= 0) dead_result(i, p);
		else throw_card(i, pi);
	}
}

void every_check_t() { // 每位玩家血量低于0用桃补血
	for (int i = 1; i <= n; i++) {
		if (a[i].hp <= 0) {
			int pp = find_card(i, 'P');
			if (pp != -1) {
				throw_card(i, pp);
				a[i].hp ++;
			}
		}
	}
}
int use_wxkj(int p, int q, char ch) { // p 使用锦囊牌,从 p 开始逆时针使用无懈可击,p 攻击目标为 q,使用的锦囊牌位 ch,返回使用者下标,若没有返回 -1
	if (!jump[q]) return -1;
	int r = p + 1;
	while (1) {
		if (r > n) r = 1;
		if (r == p) return -1; // 绕了一圈没有人用
		if (a[r].hp > 0 && (same_camp(q, r) && ch == 'F' || !same_camp(q, r) && ch == 'J')) {
			int pr = find_card(r, 'J');
			if (pr != -1) {
				throw_card(r, pr);
				return r;
			}
		}
		r ++;	
	}
}
void fight(int p, int q) { // p, q 决斗,q 先开始
	if (a[q].typ == "ZP" && a[p].typ == "MP") { // 主猪向忠猪决斗,忠猪投降
		a[q].hp --;
		if (a[q].hp <= 0) dead_result(q, p);
		return ;
	}
	while (1) {
		int pq = find_card(q, 'K');
		if (pq == -1) {
			a[q].hp --;
			if (a[q].hp <= 0) dead_result(q, p);
			break ;
		}
		throw_card(q, pq);
		int pp = find_card(p, 'K');
		if (pp == -1) {
			a[p].hp --;
			if (a[p].hp <= 0) dead_result(p, q);
			break ;
		}
		throw_card(p, pp);
	}
}

void play_cards(int p) { // 出牌
	for (int i = 1; i <= a[p].cc; i++) {
		if (a[p].hp <= 0) break ;
		if (vis[p][i]) continue ;
		every_check_t(); // 每位玩家使用一遍能使用的桃
		check_game_over();
		int kcnt = 0; // 杀的次数
		char u = a[p].C[i];
		if (u == 'P') { // 桃
			if (a[p].hp < 4) a[p].hp ++;
			throw_card(p, i);
		} else if (u == 'K') { // 杀
			if (!kcnt || (kcnt && a[p].weap)) {
				kcnt ++;
				int v = p + 1;
				if (v > n) v = 1;
				while (a[v].hp <= 0) {
					if (v > n) v = 1;
					if (v == p) {
						v = -1;
						break ;
					}
					v ++;
				}
				if (v != -1) {
					if (a[p].typ == "MP" && (jump[v] && a[v].typ == "FP" || !jump[v] && likefp[v]) || a[p].typ != "MP" && jump[v] && !same_camp(p, v)) {
						throw_card(p, i);
						if (jump[v] && !same_camp(p, v)) jump[p] = 1;
						int dp = find_card(v, 'D');
						if (dp != -1) throw_card(v, dp);
						else a[v].hp --;
						if (a[v].hp <= 0) dead_result(v, p);
					}
				}	
			}
		} else if (u == 'F') { // 决斗
			int q = find_enm_tag(p);
			if (q != -1) {
				throw_card(p, i);
				if (!same_camp(p, q) && jump[q]) jump[p] = 1; // p 对 q 表敌意,p 跳身份
				//				int pw = use_wxkj(p, q, 'F');
				//				if (pw != -1) {
				//					jump[pw] = 1; // q 跳身份且q pw 同一阵营 且 pw 使用无懈可击,所以 pw 对 q 献殷勤,所以 pw 跳身份
				//					int ppw = use_wxkj(pw, q, 'J');
				//					if (ppw != -1) { // ppw 无懈 pw 的无懈可击
				//						jump[ppw] = 1;
				//						fight(p, q);
				//					}
				//				} else fight(p, q);
				fight(p, q);
			}
		} else if (u == 'N') { // 南猪入侵
			throw_card(p, i);
			aoe_attack(p, 'K');
		} else if (u == 'W') { // 万箭齐发
			throw_card(p, i);
			aoe_attack(p, 'D');
		} else if (u == 'Z') {
			throw_card(p, i);
			a[p].weap = 1;
		}
	}
}
int main() {
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		a[i].cc = 4, a[i].hp = 4, a[i].weap = 0;
		cin >> a[i].typ >> a[i].C[1] >> a[i].C[2] >> a[i].C[3] >> a[i].C[4];
		if (a[i].typ == "MP") jump[i] = 1;
	}
	for (int i = 1; i <= m; i++) cin >> card[i];
	cur = 1; // 当前回合轮到编号为 cur
	int tst = 0;
	while (1) {
		++tst;
		if (tst > 100) break ;
		if (a[cur].hp <= 0) {
			cur ++; continue ;
		}
		if (cur > n) cur = 1;
		check_game_over();
		get_cards(cur, 2);
		//		cout << a[cur].typ << ' ';
		//		for (int i = 1; i <= a[cur].cc; i++) cout << a[cur].C[i] << ' ';
		play_cards(cur);
		//		for (int i = 1; i <= n; i++) {
		//			cout << a[i].hp << ' ';
		//		}
		//		cout << '\n';
		cur ++;
	}
	return 0;
}
2025/1/27 22:21
加载中...