头回写这么长的题目
借鉴了其他大佬的题解
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
map<char, int> type;
int tot_pigs, tot_cards, tot_fan;
char cards[2010];
struct Pig {
int shenfen; // 身份 1 :主猪 2:忠猪 3: 反猪
int life; // 血量
int state; // 当前的全局状态0 :未表 1 : 忠 2:反 3:类反
int card_type_num[5]; // 杀量 0, 闪量 1, 无懈可击量 2, 决斗量 3, 桃量 4
bool have_gear; // 是否有装备
bool alive; // 是否活着
int before_pig; // 上头猪
int next_pig; // 下头猪
char cards[2010]; // 当前卡片量
int card_num; // 卡片量
} pigs[11];
void get_card(int, char); // 摸牌
char get_card_from_cards(); // 从牌堆摸牌
void init_pig(int); // 初始化猪的参数
void delete_card(int, int); // 从牌中删除一张牌
void delete_card(int, char); // 从牌中删除一张指定牌
int get_first_kill(int); // 找到第一个目标
int get_first_fight(int); // 找到第一个决斗目标
void near_die(int, int); // 濒死
void fa_sha(int, int); // 发动杀
void fa_fight(int, int); // 发动决斗
void fa_nanzhu(int); // 发动南猪入侵
void fa_wanjian(int); // 发动万箭齐发
bool wuxie(int, int); // 使用无懈可击
bool gameover(); // 游戏是否结束
void round(int); // 回合
void printans(); // 打印结果
void get_card(int rank, char card) {
int id = type[card];
if (id <= 4)
(pigs[rank].card_type_num)[id]++;
(pigs[rank].cards)[(pigs[rank].card_num)++] = card;
}
char get_card_from_cards() {
if (tot_cards > 1) return cards[tot_cards--];
else return cards[1];
}
void init_pig(int rank) {
string shenfen;
cin >> shenfen;
if (shenfen == "MP") {
// 主猪
pigs[rank].shenfen = 1;
pigs[rank].state = 1;
}
else if (shenfen == "ZP") {
// 忠猪
pigs[rank].shenfen = 2;
}
else {
// 反猪
tot_fan++;
pigs[rank].shenfen = 3;
}
for (int i = 0; i < 4; i++) {
char card;
cin >> card;
get_card(rank, card);
}
// 初始化数据
pigs[rank].before_pig = rank == 1 ? tot_pigs : rank - 1;
pigs[rank].next_pig = rank == tot_pigs ? 1 : rank + 1;
pigs[rank].life = 4;
pigs[rank].alive = true;
}
int get_first_kill(int rank) {
int next = pigs[rank].next_pig;
// 主公
if (pigs[rank].shenfen == 1 && (pigs[next].state == 2 || pigs[next].state == 3)) {
return next;
}
// 忠臣
if (pigs[rank].shenfen == 2 && pigs[next].state == 2) {
return next;
}
// 反贼
if (pigs[rank].shenfen == 3 && pigs[next].state == 1) {
return next;
}
// 未知
return 0;
}
int get_first_fight(int rank) {
// 反贼
if (pigs[rank].shenfen == 3) return 1;
int next = pigs[rank].next_pig;
for (int i = next; i != rank; i = pigs[i].next_pig) {
// 主公
if (pigs[rank].shenfen == 1 && (pigs[i].state == 2 || pigs[i].state == 3)) {
return i;
}
// 忠臣
else if (pigs[rank].shenfen == 2 && pigs[i].state == 2) {
return i;
}
}
return 0;
}
void delete_card(int rank, int pos) {
char card = (pigs[rank].cards)[pos];
int id = type[card];
if (id <= 4)
(pigs[rank].card_type_num)[id]--;
for (int i = pos; i < pigs[rank].card_num; i++) {
(pigs[rank].cards)[i] = (pigs[rank].cards)[i + 1];
}
pigs[rank].card_num--;
}
void delete_card(int rank, char goal) {
for (int i = 0; i < pigs[rank].card_num; i++) {
char card = (pigs[rank].cards)[i];
if (card == goal) {
delete_card(rank, i);
return;
}
}
}
void near_die(int from, int rank) {
// 是否有桃子
if ((pigs[rank].card_type_num)[4]) {
delete_card(rank, 'P');
pigs[rank].life++;
}
else {
//cout << from << ' ' << rank << endl;
// 当前猪死亡
// 使用链表删去死去的猪
int prev = pigs[rank].before_pig;
int next = pigs[rank].next_pig;
pigs[prev].next_pig = next;
pigs[next].before_pig = prev;
pigs[rank].alive = false;
// 如果主公杀了忠臣
if (pigs[from].shenfen == 1 && pigs[rank].shenfen == 2) {
pigs[from].card_num = 0;
pigs[from].have_gear = false;
memset(pigs[from].card_type_num, 0, sizeof pigs[from].card_type_num);
}
// 杀了反贼
if (pigs[rank].shenfen == 3) {
tot_fan--;
// 反贼死光了就直接结束了,不用摸牌了
if (!tot_fan) return;
for (int i = 0; i < 3; i++) {
char card = get_card_from_cards();
get_card(from, card);
}
}
}
}
void fa_fight(int rank, int goal) {
// 如果攻击猪已经跳忠或跳反,就改为敌人
if (pigs[goal].state == 1 || pigs[goal].state == 2) {
pigs[rank].state = 3 - pigs[goal].state;
}
bool had_miss = wuxie(rank, pigs[goal].state); // 从发出者开始询问
if (had_miss) return;
// 如果是主猪进攻忠猪,忠猪自动放弃抵抗
if (pigs[rank].shenfen == 1 && pigs[goal].shenfen == 2) {
if (-- pigs[goal].life <= 0) {
near_die(rank, goal);
}
return;
}
do {
if ((pigs[goal].card_type_num)[0] <= 0) {
if (-- pigs[goal].life <= 0)
near_die(rank, goal);
break;
}
else {
delete_card(goal, 'K');
}
// 交换出杀的猪
swap(rank, goal);
} while (true);
}
void fa_nanzhu(int rank) {
int next = pigs[rank].next_pig;
for (int i = next; i != rank; i = pigs[i].next_pig) {
bool had_miss = wuxie(rank, pigs[i].state); // 从发出者开始询问
if (had_miss) continue;
// 出杀
if ((pigs[i].card_type_num)[0]) {
delete_card(i, 'K');
}
else {
// 当主猪被攻击且攻击的猪是未知
if (pigs[i].shenfen == 1 && pigs[rank].state == 0) {
pigs[rank].state = 3;
}
if (--pigs[i].life <= 0) {
near_die(rank, i);
// 一定要判断是否已经结束!!!
// 当达成结束条件直接结束
if (gameover()) return;
}
}
}
}
void fa_wanjian(int rank) {
int next = pigs[rank].next_pig;
for (int i = next; i != rank; i = pigs[i].next_pig) {
bool had_miss = wuxie(rank, pigs[i].state); // 从发出者开始询问
if (had_miss) continue;
// 有闪就闪
if ((pigs[i].card_type_num)[1]) {
delete_card(i, 'D');
}
else {
// 当主猪被攻击且攻击的猪是未知
if (pigs[i].shenfen == 1 && pigs[rank].state == 0) {
pigs[rank].state = 3;
}
if (--(pigs[i].life) <= 0) {
near_die(rank, i);
if (gameover()) return;
}
}
}
}
void fa_sha(int rank, int fight) {
// 把攻击的猪改为敌人
if (pigs[rank].shenfen != 1)
pigs[rank].state = 3 - pigs[fight].state;
// 有闪就闪
if ((pigs[fight].card_type_num)[1]) {
delete_card(fight, 'D');
}
else {
if (-- pigs[fight].life <= 0) {
near_die(rank, fight);
}
}
}
bool wuxie(int rank, int state) {
// 没有全局身份没人帮忙包括自己
if (state == 0 || state == 3)
return false;
for (int i = rank; ; i = pigs[i].next_pig) {
// 是否有无懈可击
if ((pigs[i].card_type_num)[2]) {
// 忠臣
if (state == 1 && (pigs[i].shenfen == 2 || pigs[i].shenfen == 1)) {
pigs[i].state = 1;
delete_card(i, 'J');
// 看看反猪有没有无懈可击
return !wuxie(i, 2);
}
// 反贼
if (state == 2 && pigs[i].shenfen == 3) {
pigs[i].state = 2;
delete_card(i, 'J');
// 看看忠猪有没有无懈可击
return !wuxie(i, 1);
}
}
// 到达前面的猪证明结束了
if (i == pigs[rank].before_pig) return false;
}
}
void round(int rank) {
// 摸牌两张
for (int i = 0; i < 2; i++) {
char card = get_card_from_cards();
get_card(rank, card);
}
bool first_kill = true;
for (int i = 0; i < pigs[rank].card_num; i++) {
char card = (pigs[rank].cards)[i];
int id = type[card];
if (gameover()) return;
// 使用杀
if (id == 0) {
if (first_kill || pigs[rank].have_gear) {
int fight = get_first_kill(rank);
if (fight) {
first_kill = false;
delete_card(rank, i);
i = i - 1; // 杀被使用
fa_sha(rank, fight);
}
}
}
// 使用决斗
else if (id == 3) {
int fight = get_first_fight(rank);
if (fight) {
delete_card(rank, i);
fa_fight(rank, fight);
// 为什么要跳到开始重新开始:
// 因为可能在发动锦囊时可能会出现多个无懈可击
// 有大量猪要跳忠或跳反,全局身份全部被改变
// 前面的杀可能可以用了
i = -1;
// 可能决斗把自己决斗死了,就不用再继续他的回合了
if (!pigs[rank].alive) return;
}
}
// 使用桃子
else if (id == 4 && pigs[rank].life < 4) {
delete_card(rank, i);
pigs[rank].life++;
i = i - 1;
}
// 使用南猪入侵
else if (id == 5) {
delete_card(rank, i);
fa_nanzhu(rank);
i = -1;
}
// 使用万箭齐发
else if (id == 6) {
delete_card(rank, i);
fa_wanjian(rank);
i = -1;
}
// 使用连弩
else if (id == 7) {
delete_card(rank, i);
pigs[rank].have_gear = true;
i = -1;
}
}
}
bool gameover() {
// 判断反猪是否全部死亡或主猪死亡
if (!tot_fan || !pigs[1].alive) return true;
return false;
}
void printans() {
if (pigs[1].alive)
cout << "MP" << endl;
else
cout << "FP" << endl;
for (int i = 1; i <= tot_pigs; i++) {
if (pigs[i].alive) {
for (int j = 0; j < pigs[i].card_num; j++) {
cout << (pigs[i].cards)[j] << ' ';
}
cout << endl;
}
else {
cout << "DEAD" << endl;
}
}
}
int main()
{
cin >> tot_pigs >> tot_cards;
type['K'] = 0, type['D'] = 1, type['J'] = 2, type['F'] = 3;
type['P'] = 4, type['N'] = 5, type['W'] = 6, type['Z'] = 7;
for (int i = 1; i <= tot_pigs; i++) init_pig(i);
for (int i = tot_cards; i > 0; i--) cin >> cards[i];
int pos = 1;
while (!gameover()) {
round(pos);
pos = pigs[pos].next_pig;
}
printans();
return 0;
}