[SDOI2010]猪国杀
一个能看的题面 : https://mubu.com/doc/2707815814591da4
晚上闲的蛋疼被Refun忽悠着写猪国杀玩然后ta告诉我这题肥肠好写
然后一下子从昨天晚上写到今天中午==
这题一堆肥肠SB的规则总之就是让你用他们的智商玩猪国杀
这是一篇没有任何意义用来装逼的题解
其实感觉这题理清思路后除了有点长也不是很难写啊比某些数据结构好写多了
附上10K的代码
然后那个忽悠我写这题的Refun一直在嘲讽我写的长TAT
#include<map>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
const int M = 2005 ;
const int N = 15 ;
using namespace std ;
int n , m ;
int think[N] , pnum , znum , fnum ;
char resp[M] ;
bool Gameover ;
struct Pig {
int id ;
bool Isshow ;
bool cloth ;
int HP ;
bool dead ;
vector < char > c ;
} p[N] ;
inline bool Win() {
if(fnum == 0 || p[1].HP == 0)
Gameover = true ;
return Gameover ;
}
inline bool Isfriend (int a , int b) {
int x = p[a].id , y = p[b].id ;
if(x == 1 || x == 2) {
if(y == 1 || y == 2) return true ;
else return false ;
}
else {
if(y == 3) return true ;
else return false ;
}
}
inline bool Miss(int now) {
for(int i = 0 ; i < p[now].c.size() ; i ++) {
char ch = p[now].c[i] ;
if(ch == 'D') {
p[now].c.erase(p[now].c.begin() + i) ;
return true ;
}
}
return false ;
}
inline bool useK(int now) {
for(int i = 0 ; i < p[now].c.size() ; i ++) {
char ch = p[now].c[i] ;
if(ch == 'K') {
p[now].c.erase(p[now].c.begin() + i) ;
return true ;
}
}
return false ;
}
inline bool useJ(int now) {
for(int i = 0 ; i < p[now].c.size() ; i ++) {
char ch = p[now].c[i] ;
if(ch == 'J') {
p[now].c.erase(p[now].c.begin() + i) ;
return true ;
}
}
return false ;
}
inline bool recover(int now) {
for(int i = 0 ; i < p[now].c.size() ; i ++) {
char ch = p[now].c[i] ;
if(ch == 'P') {
p[now].HP ++ ;
p[now].c.erase(p[now].c.begin() + i) ;
return true ;
}
}
return false ;
}
inline void Getcard(int now , int NUM) {
for(int upp = 1 ; upp <= NUM ; pnum ++ , upp ++) {
p[now].c.push_back(resp[pnum]) ;
if(pnum == m) pnum = m - 1 ;
}
}
inline bool Kill(int now , int wh) {
int Np = 0 ;
for(int i = now + 1 ; i <= n ; i ++) if(!p[i].dead)
{ Np = i ; break ; }
if(!Np) for(int i = 1 ; i < now ; i ++) if(!p[i].dead)
{ Np = i ; break ; }
if(Np == 0) return false ;
if(now == 1) {
if(p[Np].Isshow && Isfriend(now , Np)) return false ;
else if(!p[Np].Isshow && !think[Np]) return false ;
else {
p[now].c.erase(p[now].c.begin() + wh) ;
if(Miss(Np)) return true ;
p[Np].HP -- ;
if(p[Np].HP == 0) {
if(recover(Np)) return true ;
else {
p[Np].dead = true ;
if(p[Np].id == 3) fnum-- ;
else {
znum -- ;
p[now].cloth = false ;
p[now].c.clear() ;
}
if(Win()) return true ;
if(!Gameover && p[Np].id == 3) Getcard(now , 3) ;
if(p[Np].id == 2)
{ p[now].c.clear() ; p[now].cloth = false ; }
}
}
}
}
else {
if(!p[Np].Isshow) return false ;
if(p[Np].Isshow && Isfriend(now , Np)) return false ;
if(p[Np].Isshow && !Isfriend(now , Np)) {
p[now].c.erase(p[now].c.begin() + wh) ;
if(!p[now].Isshow) p[now].Isshow = true ;
if(Miss(Np)) return true ;
else {
p[Np].HP -- ;
if(p[Np].HP == 0) {
if(recover(Np)) return true ;
else {
p[Np].dead = true ;
if(p[Np].id == 3) fnum -- ;
else znum -- ;
if(Win()) return true ;
if(!Gameover && p[Np].id == 3) Getcard(now , 3) ;
}
}
}
}
}
return true ;
}
inline bool Doj(int now , int Np) {
int wx = -1 ; bool Can = true ;
while(Can) {
Can = false ;
for(int i = now ; i <= n ; i ++) {
if(p[i].dead) continue ;
if(Isfriend(Np , i) && p[Np].Isshow && wx < 0) {
if(useJ(i)) {
wx = 1 ;
Can = true ;
p[i].Isshow = true ;
}
}
if(!Isfriend(Np , i) && p[Np].Isshow && wx > 0) {
if(useJ(i)) {
wx = -1 ;
Can = true ;
p[i].Isshow = true ;
}
}
}
if(Can) continue ;
for(int i = 1 ; i < now ; i ++) {
if(p[i].dead) continue ;
if(Isfriend(Np , i) && p[Np].Isshow && wx < 0) {
if(useJ(i)) {
wx = 1 ;
Can = true ;
p[i].Isshow = true ;
}
}
if(!Isfriend(Np , i) && p[Np].Isshow && wx > 0) {
if(useJ(i)) {
wx = -1 ;
Can = true ;
p[i].Isshow = true ;
}
}
}
}
if(wx < 0) return false ;
return true ;
}
inline void Dofight(int now, int Np) {
int End = Np ;
if(now != 1 && p[Np].id != 2)
while(1) {
if(!useK(Np))
{ End = Np ; break ; }
if(!useK(now))
{ End = now ; break ; }
}
p[End].HP -- ;
int retp ;
if(End == now) retp = Np ;
else retp = now ;
if(p[End].HP == 0) {
if(recover(End)) return ;
p[End].dead = true ;
if(p[End].id == 3) fnum -- ;
else znum -- ;
if(Win()) return ;
if(!Gameover && p[End].id == 3) Getcard(retp , 3) ;
if(p[End].id == 2 && retp == 1)
{ p[retp].c.clear() ; p[retp].cloth = false ; }
}
}
inline bool Fight(int now , int wh) {
int Np = 0 ;
if(now == 1) {
for(int i = now + 1 ; i <= n ; i ++) {
if(p[i].dead) continue ;
if(p[i].Isshow && Isfriend(now , i)) continue ;
if(!p[i].Isshow && !think[i]) continue ;
Np = i ; break ;
}
if(!Np)
for(int i = 1 ; i < now ; i ++) {
if(p[i].dead) continue ;
if(p[i].Isshow && Isfriend(now , i)) continue ;
if(!p[i].Isshow && !think[i]) continue ;
Np = i ; break ;
}
}
else if(p[now].id == 2){
for(int i = now + 1 ; i <= n ; i ++) {
if(p[i].dead) continue ;
if(!p[i].Isshow) continue ;
if(Isfriend(now , i)) continue ;
Np = i ; break ;
}
if(!Np)
for(int i = 1 ; i < now ; i ++) {
if(p[i].dead) continue ;
if(!p[i].Isshow) continue ;
if(Isfriend(now , i)) continue ;
Np = i ; break ;
}
}
else if(p[now].id == 3) {
Np = 1 ;
if(!p[now].Isshow) p[now].Isshow = true ;
}
if(!Np) return false ;
p[now].c.erase(p[now].c.begin() + wh) ;
if(p[Np].id == 2 && !p[Np].Isshow) Dofight(now , Np) ;
else if(!Doj(now , Np)) Dofight(now , Np) ;
return true ;
}
inline void North(int now , int wh) {
p[now].c.erase(p[now].c.begin() + wh) ;
for(int i = now + 1 ; i <= n ; i ++) {
if(p[i].dead) continue ;
if(!Doj(now , i)) {
if(useK(i)) continue ;
else {
p[i].HP -- ;
if(p[i].id == 1) think[now] = true ;
if(p[i].HP == 0) {
if(recover(i)) continue ;
p[i].dead = true ;
if(p[i].id == 3) fnum -- ;
else znum -- ;
if(Win()) return ;
if(!Gameover && p[i].id == 3)
Getcard(now , 3) ;
if(p[i].id == 2 && now == 1)
{ p[now].c.clear() ; p[now].cloth = false ; }
}
}
}
}
for(int i = 1 ; i < now ; i ++) {
if(p[i].dead) continue ;
if(!Doj(now , i)) {
if(useK(i)) continue ;
else {
p[i].HP -- ;
if(p[i].id == 1) think[now] = true ;
if(p[i].HP == 0) {
if(recover(i)) continue ;
p[i].dead = true ;
if(p[i].id == 3) fnum -- ;
else znum -- ;
if(Win()) return ;
if(!Gameover && p[i].id == 3)
Getcard(now , 3) ;
if(p[i].id == 2 && now == 1)
{ p[now].c.clear() ; p[now].cloth = false ; }
}
}
}
}
}
inline void WJQF(int now , int wh) {
p[now].c.erase(p[now].c.begin() + wh) ;
for(int i = now + 1 ; i <= n ; i ++) {
if(p[i].dead) continue ;
if(!Doj(now , i)) {
if(Miss(i)) continue ;
else {
p[i].HP -- ;
if(p[i].id == 1) think[now] = true ;
if(p[i].HP == 0) {
if(recover(i)) continue ;
p[i].dead = true ;
if(p[i].id == 3) fnum -- ;
else znum -- ;
if(Win()) return ;
if(!Gameover && p[i].id == 3)
Getcard(now , 3) ;
if(p[i].id == 2 && now == 1)
{ p[now].c.clear() ; p[now].cloth = false ; }
}
}
}
}
for(int i = 1 ; i < now ; i ++) {
if(p[i].dead) continue ;
if(!Doj(now , i)) {
if(Miss(i)) continue ;
else {
p[i].HP -- ;
if(p[i].id == 1) think[now] = true ;
if(p[i].HP == 0) {
if(recover(i)) continue ;
p[i].dead = true ;
if(p[i].id == 3) fnum -- ;
else znum -- ;
if(Win()) return ;
if(!Gameover && p[i].id == 3)
Getcard(now , 3) ;
if(p[i].id == 2 && now == 1)
{ p[now].c.clear() ; p[now].cloth = false ; }
}
}
}
}
}
inline void Solve(int now) {
bool Can = true ;
bool killuse = false ;
while(Can) {
Can = false ;
if(Win()) return ;
for(int i = 0 ; i < p[now].c.size() ; i ++) {
if(Win()) return ;
if(p[now].dead) return ;
char ch = p[now].c[i] ;
if(ch == 'P') {
if(p[now].HP < 4) {
p[now].HP ++ ;
p[now].c.erase(p[now].c.begin() + i) ;
Can = true ; break ;
}
}
else if(ch == 'K') {
if(killuse == true && p[now].cloth == false) continue ;
if(Kill(now , i)) {
Can = true ;
killuse = true ; break ;
}
}
else if(ch == 'F') {
if(Fight(now , i) ) {
Can = true ;
break ;
}
}
else if(ch == 'N') {
North(now , i) ;
Can = true ;
break ;
}
else if(ch == 'W') {
WJQF(now , i) ;
Can = true ;
break ;
}
else if(ch == 'Z') {
p[now].cloth = true ; Can = true ;
p[now].c.erase(p[now].c.begin() + i) ; break ;
}
}
}
}
int main() {
scanf("%d%d",&n,&m) ; pnum = 1 ;
for(int i = 1 ; i <= n ; i ++) {
p[i].HP = 4 ; p[i].Isshow = false ;
p[i].cloth = false ; p[i].dead = false ;
char s1[5] , s[6][5] ;
scanf("%s%s%s%s%s",s1,s[1],s[2],s[3],s[4]) ;
if(s1[0] == 'M') p[i].id = 1 , znum ++ ;
else if(s1[0] == 'Z') p[i].id = 2 , znum ++ ;
else p[i].id = 3 , fnum ++ ;
for(int j = 1 ; j <= 4 ; j ++) p[i].c.push_back(s[j][0]) ;
}
p[1].Isshow = true ;
for(int i = 1 ; i <= m ; i ++) {
char s[5] ;
scanf("%s",s) ;
resp[i] = s[0] ;
}
int now = 1 ;
while(!Gameover) {
if(Win()) break ;
while(p[now].dead) {
++ now ;
if(now > n) now = 1 ;
}
Getcard(now , 2) ;
Solve(now) ;
++ now ;
if(now > n) now = 1 ;
}
if(p[1].HP == 0) printf("FP\n") ;
else printf("MP\n") ;
for(int i = 1 ; i <= n ; i ++) {
if(p[i].dead) printf("DEAD\n") ;
else {
for(int j = 0 ; j < p[i].c.size() ; j ++)
printf("%c ",p[i].c[j]) ;
printf("\n") ;
}
}
return 0 ;
}