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;
}