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