UOJ Logo ZTXX的博客

博客

题解 P2482 【[SDOI2010]猪国杀】

2019-12-21 11:42:29 By ZTXX

一个正常人是不会做这种题的...

某年某月某天,我校机房有个可怜人被人强行立了个flag:9月月底做不出来luoguP2482就女装!于是他拼命的调代码。5分,10分,25分......95分。最后实在不行了求救了机房大佬WY才AC。

这位同志的精神感动了机房,于是全机房都开始疯狂的调这道题。我也不幸幸运的成为了其中的一员。

其实这道题就是模拟,大概是因为我平时闲的没事喜欢做游戏,所以感觉挺简单的。

把各种行为封装成自由函数,当然如果你想建class也没有问题。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

/*
¡¾ÌÒ¡¿ P
¡¾É±¡¿ K
¡¾ÉÁ¡¿ D
¡¾¾ö¶·¡¿ F
¡¾ÄÏÂùÈëÇÖ¡¿ N
¡¾Íò¼ýÆë·¢¡¿ W
¡¾ÎÞи¿É»÷¡¿ J
¡¾Öî¸ðÁ¬åó¡¿ Z
*/

const int MAX_PLAYER_NUM = 100 + 5;
const int MAX_CARD_NUM = 2000 + 5;
class PIG
{
public:
    int        card_num;
    int        life_num;
    int        _next;
    int        _last;
    char    identity;
    char    card[MAX_CARD_NUM];
    bool    isGetedZgln;
} A[MAX_PLAYER_NUM];
char    id_in_king[MAX_PLAYER_NUM];     //在主公眼里诸猪的身份
char    card_set[MAX_CARD_NUM];
char    scanner[MAX_PLAYER_NUM];
int        n, m, bad_man_num;
bool    GG;  //主公是否GG

inline     void        initt(                             );
inline     void        start(                            );
inline     void        mopai(       int fuck       );  //不知道怎么命名了...
inline     void        nmrqq(         int fuck       );
inline     void        wjqff(         int fuck       );
inline     void        jisha( int Killer, int GGer );
inline     void        killl( int Killer, int GGer );
inline     void        jdddd( int Killer, int GGer );
inline     bool        wxkjj(int x1, int x2, int x3);   //为了对齐

signed main()
{
    initt();
    start();
    if (A[1].life_num <= 0)    puts("FP");
    else puts("MP");
    for (int i = 1; i <= n; ++i)
    {
        if (A[i].life_num <= 0)    puts("DEAD");
        else
        {
            for (int j = 1; j <= A[i].card_num; ++j)
                if (A[i].card[j] != 'U')    printf("%c ", A[i].card[j]);
            puts("");
        }
    }
    return 0;
}

inline void    initt()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i)    A[i]._next = i + 1, A[i]._last = i - 1;
    A[n]._next = 1, A[1]._last = n;
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j < MAX_CARD_NUM; ++j)    A[i].card[j] = 'U';
        scanf("%s", scanner);
        A[i].identity = scanner[0];
        for (int j = 1; j < 5; ++j)    scanf("%s", scanner), A[i].card[j] = scanner[0];
        A[i].life_num = A[i].card_num = 4;
        if (A[i].identity == 'F')    bad_man_num++;
        A[i].isGetedZgln = false;
    }
    id_in_king[1] = 'M';
    for (int i = 2; i <= n; ++i)    id_in_king[i] = 'U';
    for (int i = 1; i <= m; ++i)    scanf("%s", scanner), card_set[m - i + 1] = scanner[0];
}

inline void start()
{
    char now_card;
    GG = true;
    if (bad_man_num) GG = false;
    if (GG)        return;
    for (int i = 1; i; i = A[i]._next)
    {
        mopai(i), mopai(i);
        bool isKilled = true;
        for (int j = 1; j <= A[i].card_num; ++j)
        {
            if (A[i].card[j] != 'U')
            {
                if (!A[i].life_num)    break;
                now_card = A[i].card[j];

                if (now_card == 'P')
                {
                    if (A[i].life_num != 4)    A[i].life_num++, A[i].card[j] = 'U';
                    continue;
                }

                if (now_card == 'K')
                {
                    if (!isKilled && !A[i].isGetedZgln)    continue;
                    if ((A[i].identity == 'M') && (id_in_king[A[i]._next] != 'L') && (id_in_king[A[i]._next] != 'F'))
                        continue;
                    if ((A[i].identity == 'Z') && (id_in_king[A[i]._next] != 'F'))
                        continue;
                    if ((A[i].identity == 'F') && (id_in_king[A[i]._next] != 'Z') && (id_in_king[A[i]._next] != 'M'))
                        continue;
                    A[i].card[j] = 'U';
                    killl(i, A[i]._next);
                    id_in_king[i] = A[i].identity;
                    isKilled = false;
                    if (GG)    return;
                    continue;
                }

                if (now_card == 'F')
                {
                    if (A[i].identity == 'F')
                    {
                        A[i].card[j] = 'U';
                        jdddd(i, 1);
                        id_in_king[i] = A[i].identity;
                        if (GG)    return;
                        j = 0;
                        continue;
                    }
                    for (int k = A[i]._next; k != i; k = A[k]._next)
                    {
                        if ((A[i].identity == 'M' && (id_in_king[k] == 'L' || id_in_king[k] == 'F')) || (A[i].identity == 'Z' && id_in_king[k] == 'F'))
                        {
                            A[i].card[j] = 'U';
                            jdddd(i, k);
                            id_in_king[i] = A[i].identity;
                            if (GG)    return;
                            j = 0;
                            break;
                        }
                    }
                    continue;
                }


                if (now_card == 'N')
                {
                    A[i].card[j] = 'U';
                    nmrqq(i);
                    if (GG)    return;
                    j = 0;
                    continue;
                }

                if (now_card == 'W')
                {
                    A[i].card[j] = 'U';
                    wjqff(i);
                    if (GG)    return;
                    j = 0;
                    continue;
                }

                if (now_card == 'Z')
                {
                    A[i].isGetedZgln = true;
                    A[i].card[j] = 'U';
                    j = 0;
                    continue;
                }
            }
        }
    }
}

inline void mopai(int fuck)
{
    if (!m)    m++;
    A[fuck].card[++A[fuck].card_num] = card_set[m];
    m--;
}

inline void nmrqq(int fuck)
{
    for (int shit = A[fuck]._next; shit != fuck; shit = A[shit]._next)
    {
        if (!wxkjj(fuck, shit, 1))
        {
            int i;
            for (i = 1; i <= A[shit].card_num; ++i)
            {
                if (A[shit].card[i] == 'K')
                {
                    A[shit].card[i] = 'U';
                    break;
                }
            }
            if (i > A[shit].card_num)
            {
                A[shit].life_num--;
                if (shit == 1 && id_in_king[fuck] == 'U')    id_in_king[fuck] = 'L';
                if (!A[shit].life_num) jisha(fuck, shit);
                if (GG)    return;
            }
        }
    }
}

inline void wjqff(int fuck)
{
    for (int shit = A[fuck]._next; shit != fuck; shit = A[shit]._next)
    {
        if (!wxkjj(fuck, shit, 1))
        {
            int i;
            for (i = 1; i <= A[shit].card_num; ++i)
            {
                if (A[shit].card[i] == 'D')
                {
                    A[shit].card[i] = 'U';
                    break;
                }
            }
            if (i > A[shit].card_num)
            {
                A[shit].life_num--;
                if (shit == 1 && id_in_king[fuck] == 'U')    id_in_king[fuck] = 'L';
                if (!A[shit].life_num)    jisha(fuck, shit);
                if (GG)    return;
            }
        }
    }
}

inline void jisha(int Killer, int GGer)
{
    for (int i = 1; i <= A[GGer].card_num; ++i)
    {
        if (A[GGer].card[i] == 'P')
        {
            A[GGer].card[i] = 'U';
            A[GGer].life_num++;
            return ;
        }
    }

    A[A[GGer]._next]._last = A[GGer]._last;
    A[A[GGer]._last]._next = A[GGer]._next;

    if (GGer == 1)
    {
        GG = true;
        return ;
    }

    if (A[GGer].identity == 'F')    bad_man_num--;

    if (!bad_man_num)
    {
        GG = true;
        return ;
    }

    if (A[GGer].identity == 'F')    mopai(Killer), mopai(Killer), mopai(Killer);

    if (A[GGer].identity == 'Z' && A[Killer].identity == 'M')    A[Killer].card_num = 0, A[Killer].isGetedZgln = false;
}

inline void killl(int Killer, int GGer)
{
    for (int i = 1; i <= A[GGer].card_num; ++i)
    {
        if (A[GGer].card[i] == 'D')
        {
            A[GGer].card[i] = 'U';
            return ;
        }
    }
    A[GGer].life_num--;
    if (!A[GGer].life_num)    jisha(Killer, GGer);
}

inline void jdddd(int Killer, int GGer)
{
    int fuck, shit;
    if (wxkjj(Killer, GGer, 1))    return ;

    if (Killer == 1 && A[GGer].identity == 'Z')
    {
        A[GGer].life_num--;
        if (!A[GGer].life_num)    jisha(Killer, GGer);
        return ;
    }

    fuck = shit = 1;

    while (233)
    {
        while (A[GGer].card[fuck] != 'K' && fuck <= A[GGer].card_num)    ++fuck;
        if (fuck > A[GGer].card_num)
        {
            A[GGer].life_num--;
            if (!A[GGer].life_num)    jisha(Killer, GGer);
            return ;
        }
        else A[GGer].card[fuck] = 'U';

        while (A[Killer].card[shit] != 'K' && shit <= A[Killer].card_num)    ++shit;
        if (shit > A[Killer].card_num)
        {
            A[Killer].life_num--;
            if (!A[Killer].life_num)    jisha(GGer, Killer);
            return ;
        }
        else A[Killer].card[shit] = 'U';
    }
}

inline bool wxkjj(int x1, int x2, int x3)
{
    int i = x1;
    while (233)
    {
        if (x3 == 1)
        {
            if (id_in_king[x2] == A[i].identity || (id_in_king[x2] == 'M' && A[i].identity == 'Z') || (id_in_king[x2] == 'Z' && A[i].identity == 'M'))
            {
                for (int j = 1; j <= A[i].card_num; ++j)
                {
                    if (A[i].card[j] == 'J')
                    {
                        A[i].card[j] = 'U';
                        id_in_king[i] = A[i].identity;
                        return !wxkjj(i, x1, 0);
                    }
                }
            }
        }

        else
        {
            if (((A[i].identity == 'M' || A[i].identity == 'Z') && id_in_king[x1] == 'F') || (A[i].identity == 'F' && (id_in_king[x1] == 'M' || id_in_king[x1] == 'Z')))
            {
                for (int j = 1; j <= A[i].card_num; ++j)
                {
                    if (A[i].card[j] == 'J')
                    {
                        A[i].card[j] = 'U';
                        id_in_king[i] = A[i].identity;
                        return !wxkjj(i, x1, 0);
                    }
                }
            }
        }
        i = A[i]._next;
        if (i == x1)    break;
    }
    return false;
}

评论

暂无评论

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。