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

原文地址:https://www.cnblogs.com/beretty/p/9797735.html

时间: 2024-10-10 10:04:14

[SDOI2010]猪国杀的相关文章

洛谷P2482 [SDOI2010]猪国杀

题目:https://www.luogu.org/problemnew/show/P2482 题目描述 <猪国杀>是一种多猪牌类回合制游戏,一共有三种角色:主猪,忠猪,反猪.每局游戏主猪有且只有一只,忠猪和反猪可以有多只,每只猪扮演一种角色. 游戏目的: 主猪(MP):自己存活的情况下消灭所有的反猪. 忠猪(ZP):不惜一切保护主猪,胜利条件与主猪相同. 反猪(AP):杀死主猪. 游戏过程: 游戏开始时候,每个玩家手里都会有4张牌,且体力上限和初始体力都是4. 开始游戏时,从主猪开始,按照逆时

Luogu P2482 [SDOI2010]猪国杀

Pig Country Kill 很古怪的翻译,不过它确实叫猪(Pig)国(Country)杀(Kill). 我们来好好整理一下这道题目.题面虽较长,但内容基本清晰,只是有部分很Pig的操作部分,很容易让第一次看见这道题目的人百思不得其解. 先整理一下这道长长的题面. First:人物 四位玩家,初始四张手牌,血量上限\(4\),初始血量\(4\),会告诉你整个牌堆的牌,每位玩家每个回合从牌堆顶部抽走两张牌,放在自己手牌的右侧.人物分主猪,忠猪,和反猪,主猪只有一只,反猪和忠猪可以有多只,反猪全

Luogu2482 [SDOI2010]猪国杀

题意 ...... https://www.luogu.org/problemnew/show/P2482 总结 题解好像没什么好写的 一些经验吧...... 提前分配好一些比较好的变量名 建议先声明函数再定义函数 打开Dev-C++的代码结构或者自己在草稿纸上写结构 每次调试之前自己浏览一遍代码并手推一遍样例,特别是修改了之后注意自己修改的地方,不要编译了历史版本 不要写的十分复杂,能简单写简单写 善用assert 善用注释 1 //Created By Creeper_LKF 2 //Cau

bzoj1972: [Sdoi2010]猪国杀 模拟

模拟.认真读题,理清思路. #include<cstdio> #include<list> #include<cstdlib> const int N=10; #define FOR(a,k)for(A k=P[a].begin();k!=P[a].end();++k) using namespace std; int n,m; int HP[N],ST[N]; bool ID[N],Z[N]; list<char> P[N]; typedef list&l

洛谷P2482 猪国杀

题目描述 <猪国杀>是一种多猪牌类回合制游戏,一共有三种角色:主猪,忠猪,反猪.每局游戏主猪有且只有一只,忠猪和反猪可以有多只,每只猪扮演一种角色. 游戏目的: 主猪(MP):自己存活的情况下消灭所有的反猪. 忠猪(ZP):不惜一切保护主猪,胜利条件与主猪相同. 反猪(AP):杀死主猪. 游戏过程: 游戏开始时候,每个玩家手里都会有4张牌,且体力上限和初始体力都是4. 开始游戏时,从主猪开始,按照逆时针方向(数据中就是按照编号从1,2,3..n,1..的顺序)依次行动. 每个玩家自己的回合可以

Yali 19 - 8 - 6 test T2 猪国(pig) 题解

T2 猪国 题?描述 猪国是?个由 \(n\) 个城市组成的国家. 国王意识到了"要致富,先修路"这句话的重要性,它决定?规模修路.不巧的是,猪国的 猪们不太会?程,于是只能请隔壁鸡国的鸡建狂魔来帮忙修路.鸡建狂魔看不起猪,于是随 便建设了 \(m\) 条单向的路.尽管如此,每条路还是产?了或多或少的价值. 路修好了,经济却上不来.国王经过调研,发现了道路的巨?缺陷.具体来说,猪?们?向 感不好,?旦存在若?条路能组成?个环,那么可怜的猪?就有可能在环??绕来绕去,这 样甚?会产?反效

大神刷题表

9月27日 后缀数组:[wikioi3160]最长公共子串 dp:NOIP2001统计单词个数 后缀自动机:[spoj1812]Longest Common Substring II [wikioi3160]最长公共子串 [spoj7258]Lexicographical Substring Search 扫描线+set:[poj2932]Coneology 扫描线+set+树上删边游戏:[FJOI2013]圆形游戏 结论:[bzoj3706][FJ2014集训]反色刷 最小环:[poj1734

联赛之前的题表(已完成)汇总(可能有遗漏)

联赛之前的搞搞(其实是懒得分类) 博弈论 poj3537 poj1704 hdu5996两个插头 HDU1693 Eat the Trees COGS1283. [HNOI2004] 邮递员kdtree板子1941: [Sdoi2010]Hide and Seek旋转卡壳 pj2187凸包 cogs896 bzoj2829 信用卡凸包莫比乌斯反演基础 bzoj 4173 zhao gui lv bzoj 3529 mobiwus bzoj 4407 mobiwus bzoj 2818 mobiw

SDOI2010选做

\(Round1~D1T1\)外星千足虫 \(BSOJ2793\)--高斯消元解异或方程组 简述 有\(n\)个数\(\{a_i\}\) 给出\(m\)个信息,每个信息给出\(\displaystyle{(\sum_{i=1}^m a_{b_i})\bmod 2}\)(\(\{b_i\}\)是\({1,2,\cdots,n}\)的子集) 求最少几次操作即可确定可能取值 Solution \(70pts'\) 给出的信息可以转化为\(\displaystyle{\oplus_{i=1}^m a_{