[SDOI2010]猪国杀

Posted beretty

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SDOI2010]猪国杀相关的知识,希望对你有一定的参考价值。

一个能看的题面 : https://mubu.com/doc/2707815814591da4

晚上闲的没事干被Refun忽悠着写猪国杀玩

然后一下子写到现在

浪费了一晚上+一上午

这题一堆肥肠SB的规则总之就是让你用他们的智商玩猪国杀

这是一篇没有任何意义的题解

附上10K的代码

然后那个忽悠我的人一直在嘲讽我写的长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
") ;
    else printf("MP
") ;
    for(int i = 1 ; i <= n ; i ++) {
        if(p[i].dead) printf("DEAD
") ;
        else {
            for(int j = 0 ; j < p[i].c.size() ; j ++)
                printf("%c ",p[i].c[j]) ;
            printf("
") ;
        }
    }
    return 0 ;
}

以上是关于[SDOI2010]猪国杀的主要内容,如果未能解决你的问题,请参考以下文章

P2482 [SDOI2010] 猪国杀

Luogu2482 [SDOI2010]猪国杀

[Sdoi2010]猪国杀

[SDOI2010]猪国杀

洛谷P2482 [SDOI2010]猪国杀

[SDOI2010]猪国杀