「BZOJ 1972」[SDOI2010]猪国杀

这什么鬼鬼题呀

大概就所有东西都封装成函数,看起来优美又好写。

恰好两百行!

#include 
#include 
#include 
int n, m, id[12], yes[12] = {1}, HP[12], FP;
bool arm[12], master[12];
typedef std::list<char>::iterator iter;
std::list<char> D[12], Card;
std::list<int> Player;
char last;
void Draw(int now)
{
    if(!Card.empty()){ D[now].push_back(Card.front()); Card.pop_front(); }
    else D[now].push_back(last);
}
int find_sum; char find_value;
bool check(const char &value)
{
    if(find_sum && value == find_value)
    {
        --find_sum; 
        return 1; 
    }
    return 0; 
}
void Report()
{
    for(int i = 0; i < n; ++i)
        if(HP[i] <= 0) puts("DEAD");
        else
        {
            for(iter j = D[i].begin(); j != D[i].end(); ++j) printf("%c ", *j); 
            puts("");
        }
    exit(0);
}
void Drop(int a, int b)
{
    --HP[b];
    if(HP[b] == 0)
    {
        find_sum = 1; find_value = 'P';
        D[b].remove_if(check);
        if(!find_sum){ ++HP[b]; return ; }
        if(b == 0){ puts("FP"); Report(); }
        if(id[b] == 2 && --FP){ Draw(a); Draw(a); Draw(a); }
        if(FP == 0){ puts("MP"); Report(); }
        if(id[b] == 1 && a == 0){ D[a].clear(); arm[a] = 0; }
    }
}
bool Kill(int now, iter h)
{
    find_sum = 1; find_value = 'D';
    for(int i = 1; i < n; ++i) if(HP[(i + now) % n] > 0)
    {
        int v = (i + now) % n;
        if(now == 0 && master[v]);
        else if(!yes[v] || yes[v] == id[now]) return 0;
        yes[now] = id[now]; master[now] = 0; 
        D[now].erase(h); D[v].remove_if(check);
        if(find_sum) Drop(now, v);
        return 1;
    }
    return 0;
}
bool Miss(int now, int pos, bool flag = 0)
{
    for(int i = 0; i < n; ++i)
    {
        int v = (i + now) % n;
        if(HP[v] > 0 && ((!flag && id[v] == yes[pos]) || (flag && id[v] != yes[now])))
        {
            find_sum = 1; find_value = 'J';
            D[v].remove_if(check);
            if(!find_sum)
            {
                yes[v] = id[v]; master[v] = 0;
                return !Miss(v, now, 1);
            }
        }
    }
    return 1;
}
bool Fight(int now, iter h)
{
    int pos = -1;
    if(id[now] == 2){ pos = 0; yes[now] = id[now]; master[now] = 0; }
    else
    {
        for(int i = 1; i < n; ++i) 
        {
            int v = (i + now) % n;
            if(HP[v] > 0 && ((yes[v] && yes[v] != id[now]) || (now == 0 && master[v])))
            {
                yes[now] = id[now]; master[now] = 0; 
                pos = v; break;
            }
        }
        if(pos == -1) return 0;
    }
    D[now].erase(h); 
    if(!Miss(now, pos)) return 1;
    int s1 = 0, s2 = 0;
    for(iter i = D[now].begin(); i != D[now].end(); ++i) if(*i == 'K') ++s1;
    for(iter i = D[pos].begin(); i != D[pos].end(); ++i) if(*i == 'K') ++s2;
    if(now == 0 && id[pos] == 1) s2 = 0;
    find_value = 'K';
    if(s1 >= s2)
    {
        find_sum = s2; D[now].remove_if(check);
        find_sum = s2; D[pos].remove_if(check);
        Drop(now, pos);
    }
    else
    {
        find_sum = s1; D[now].remove_if(check);
        find_sum = s1 + 1; D[pos].remove_if(check);
        Drop(pos, now);
    }
    return 1;
}
void For_All(int pos, char t)
{
    for(int i = 1; i < n; ++i)
    {
        int v = (i + pos) % n;
        if(HP[v] > 0 && Miss(pos, v))
        {
            find_sum = 1; find_value = t == 'N' ? 'K' : 'D';
            D[v].remove_if(check);
            if(find_sum) 
            {
                if(v == 0 && !yes[pos]) master[pos] = 1; 
                Drop(pos, v);
            }
        }
    }
}
void Play(int now)
{
    if(HP[now] <= 0) return ;
    bool flag, used_kill = 1; int pos;
    do
    {
        flag = 0;
        for(iter i = D[now].begin(); i != D[now].end(); ++i)
        {
            if(*i == 'Z'){ arm[now] = true; D[now].erase(i); flag = 1; break; }
            if(*i == 'P' && HP[now] < 4){ D[now].erase(i); ++HP[now]; flag = 1; break; }
            if(*i == 'N' || *i == 'W'){ D[now].erase(i); For_All(now, *i); flag = 1; break; }
            if(*i == 'F' && Fight(now, i)){ flag = 1; break; }
            if(*i == 'K' && (used_kill || arm[now]) && Kill(now, i)){ used_kill = 0; flag = 1; break; }
        }
    }
    while(flag && HP[now] > 0);
}
void Game()
{
    if(FP == 0){ puts("MP"); Report(); }
    std::list<int>::iterator turn = Player.begin(), cur;
    while(1)
    {
        if(HP[*turn] > 0)
        {
            Draw(*turn); Draw(*turn); 
            Play(*turn); 
        }
        cur = turn; ++turn;
        if(turn == Player.end()) turn = Player.begin();
        if(HP[*cur] <= 0) Player.erase(cur);
    }
}
void Import()
{
    scanf("%d %d", &n, &m); 
    char str[5];
    for(int i = 0; i < n; ++i)
    {
        scanf("%s", str);
        if(str[0] == 'F'){ id[i] = 2; ++FP; }
        else id[i] = 1;
        for(int j = 0; j < 4; ++j)
        {
            scanf("%s", str); 
            D[i].push_back(str[0]);
        }
    }
    for(int i = 0; i < m; ++i)
    { 
        scanf("%s", str); 
        Card.push_back(str[0]); 
    }
    last = Card.back();
    for(int i = 0; i < n; ++i) HP[i] = 4;
    for(int i = 0; i < n; ++i) Player.push_back(i);
}
int main()
{
    Import(); Game();
    return 0;
}

你可能感兴趣的:(模拟)