新手过了样例然后全错,能不能帮忙看一看。。。
查看原帖
新手过了样例然后全错,能不能帮忙看一看。。。
319478
zhibuba楼主2020/8/9 20:50
#include <iostream>
#include <vector>
#include <list>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cassert>

using namespace std;

struct Role;
enum Card {P, K, D, F, N, W, J, Z};
enum Status {MP, ZP, FP, LFP, UK};
enum Behavior {Kind, Hosti, Like_Hosti};

int n, m, living;
int pos_id[10];
int FP_cnt;
vector<Card> card_heap;

void cause_injury(int source, int target);
void settle_death(int source, int target);
void judge_status(int source, int target, Behavior behavior);
bool ask_J(int role, Behavior behavior);
int next_role(int role);

bool is_unknown(int a);
bool is_friend(int source, int target);
bool is_enemy(int source, int target);

istream & operator>>(istream & is, Status & s);
istream & operator>>(istream & is, Card & c);
ostream & operator<<(ostream & os, Card c);

void game_init();
void game_on();
void game_terminate(Status winner);

int main()
{
    game_init();
    game_on();
} 

struct Role
{
    int id, pos;
    Status status, known_status;
    int health_point, health_limit;
    int hand_card[8], armed_card;
    list<Card> hand_card_list;

    Role() = default;
    Role(Status s, int i, Card c1, Card c2, Card c3, Card c4) :
        id(i), pos(i), status(s), known_status(UK), health_point(4), health_limit(4),
        hand_card{}, armed_card(0), hand_card_list{}
        {
            pos_id[pos] = id;
            if (s == MP)
                known_status = MP;
            hand_card[c1]++, hand_card[c2]++, hand_card[c3]++, hand_card[c4]++;
            hand_card_list.push_back(c1), hand_card_list.push_back(c2), hand_card_list.push_back(c3), hand_card_list.push_back(c4);
        }

    void get_card(int num)
    {
        while (num--)
        {
            Card t = card_heap.back();
            card_heap.pop_back();
            hand_card[t]++;
            hand_card_list.push_back(t);
        }
    }

    void del_card(Card c)
    {
        for (auto p = hand_card_list.begin(); p != hand_card_list.end(); ++p)
        {
            if (*p == c)
            {
                hand_card_list.erase(p);
                break;
            }
        }
    }

    void play_stage();

    void use_P();
    void use_K(int b);
    void use_F(int b);
    void use_N();
    void use_W();
    void use_Z();
};

Role roles[10];

void Role::play_stage()
 {
    bool K_used = false;
    while (hand_card[P] && health_point < health_limit)
        use_P();
    while (hand_card[Z])
        use_Z();
    while (hand_card[W])
        use_W();
    while (hand_card[N])
        use_N();
    for (int t = 1, i = next_role(id); t < living; t++, i = next_role(id))
    {
        if (is_enemy(id, i))
        {
            while (hand_card[K] && (!K_used || armed_card) && t == 1 && roles[i].health_point)
            {
                use_K(i);
                K_used = true;
            }
            while (hand_card[F] && roles[i].health_point)
                use_F(i);
        }
    }
 }

void Role::use_P() 
{
    health_point++;
    hand_card[P]--, del_card(P);
}

void Role::use_K(int b) 
{
    hand_card[K]--, del_card(K);
    if (roles[b].hand_card[D])
        roles[b].hand_card[D]--, roles[b].del_card(D);
    else
        cause_injury(id, b);
    if (is_unknown(id))
        judge_status(id, b, Hosti);
}

void Role::use_F(int b)
{
    hand_card[F]--, del_card(F);
    if (ask_J(b, Kind))
        return;
    while (true)
    {
        if (roles[b].hand_card[K] && !(roles[b].status == ZP && status == MP))
            roles[b].hand_card[K]--, roles[b].del_card(K);
        else
        {
            cause_injury(id, b);
            break;
        }
        if (hand_card[K])
            hand_card[K]--, del_card(K);
        else
        {
            cause_injury(b, id);
            break;
        }
    }
    if (is_unknown(id))
        judge_status(id, b, Hosti);
}

void Role::use_N()
{
    hand_card[N]--, del_card(N);
    for (int t = 1, i = next_role(id); t < living; t++, i = next_role(i))
    {
        if (roles[i].health_point && i != id)
        {
            if (ask_J(i, Kind))
                ;
            else if (roles[i].hand_card[K])
                roles[i].hand_card[K]--, roles[i].del_card(K);
            else
                cause_injury(id, i);
        }
    }
}

void Role::use_W()
{
    hand_card[W]--, del_card(W);
    for (int t = 1, i = next_role(id); t < living; t++, i = next_role(i))
    {
        if (roles[i].health_point && i != id)
        {
            if (ask_J(i, Kind))
                ;
            else if (roles[i].hand_card[D])
                roles[i].hand_card[D]--, del_card(D);
            else
                cause_injury(id, i);
        }
    }
}

void Role::use_Z()
{
    armed_card = 1;
    hand_card[Z]--, del_card(Z);
}


int next_role(int a)
{
    return pos_id[(roles[a].pos + 1) % living];
}

bool is_unknown(int a)
{
    return roles[a].known_status == UK || roles[a].known_status == LFP;
}

bool is_friend(int a, int b)
{
    return ((roles[b].known_status == MP || roles[b].known_status == ZP) && 
            (roles[a].status == MP || roles[a].status == ZP)) ||
            (roles[b].known_status == FP && roles[a].known_status == FP);
}

bool is_enemy(int a, int b)
{
    return ((roles[b].known_status == MP || roles[b].known_status == ZP) && 
            roles[a].status == FP) ||
            (roles[b].known_status == FP &&
            (roles[b].known_status == MP && roles[a].known_status == ZP)) ||
            (roles[b].known_status == LFP && roles[a].known_status == MP);
}

bool ask_J(int a, Behavior o)
{
    if (is_unknown(a))
        return false;
    for (int t = 1, i = a; t <= living; t++, i = next_role(i))
    {
        if (roles[i].hand_card[J] && ((o == Kind && is_friend(i, a))
            || (o == Hosti && is_enemy(i, a))))
        {
            roles[i].hand_card[J]--, roles[i].del_card(J);
            if (is_unknown(a))
                judge_status(i, a, o);
            return !ask_J(i, Hosti);
        }
    }
    return false;
}

void cause_injury(int a, int b)
{
    roles[b].health_point--;
    if (roles[b].health_point == 0)
    {
        if (roles[b].hand_card[P])
            roles[b].use_P();
        else
            settle_death(a, b);
    }
    if (is_unknown(a))
        judge_status(a, b, Like_Hosti);
}

void settle_death(int a, int b)
{
    switch (roles[b].status)
    {
        case MP:
            game_terminate(FP);
            break;
        case ZP:
            if (roles[a].status == MP)
                memset(roles[a].hand_card, 0, sizeof(roles[a].hand_card)), roles[a].hand_card_list.clear();
            break;
        case FP:
            FP_cnt--;
            if (FP_cnt == 0)
                game_terminate(MP);
            roles[a].get_card(3);
            break;
    }
    for (int i = 0; i < n; i++)
        if (roles[i].pos > roles[b].pos)
            pos_id[--roles[i].pos] = i;
    living--;
}

void judge_status(int a, int b, Behavior t)
{
    switch (t)
    {
        case Kind:
            switch (roles[b].known_status)
            {
                case MP: case ZP:
                    roles[a].known_status = ZP;
                    break;
                case FP:
                    roles[a].known_status = FP;
                    break;
            }
            break;
        case Hosti:
            switch (roles[b].known_status)
            {
                case MP: case ZP:
                    roles[a].known_status = FP;
                    break;
                case FP:
                    roles[a].known_status = ZP;
                    break;
            }
            break;
        case Like_Hosti:
            if (roles[b].known_status == MP)
                roles[a].known_status = LFP;
            break;
    }
}

istream & operator>>(istream & is, Status & s)
{
    string str;
    is >> str;
    switch (str[0])
    {
        case 'M': s = MP; break;
        case 'Z': s = ZP; break;
        case 'F': s = FP; break;
    } 
    return is;
}

istream & operator>>(istream & is, Card & c)
{
    char ch;
    is >> ch;
    switch (ch)
    {
        case 'P': c = P; break;
        case 'K': c = K; break;
        case 'D': c = D; break;
        case 'F': c = F; break;
        case 'N': c = N; break;
        case 'W': c = W; break;
        case 'J': c = J; break;
        case 'Z': c = Z; break;
    } 
    return is;
}

ostream & operator<<(ostream & os, Card c)
{
    switch (c)
    {
        case P: os << 'P'; break;
        case K: os << 'K'; break;
        case D: os << 'D'; break;
        case F: os << 'F'; break;
        case N: os << 'N'; break;
        case W: os << 'W'; break;
        case J: os << 'J'; break;
        case Z: os << 'Z'; break;
    } 
    return os;
}

void game_init()
{
    cin >> n >> m;
    living = n;
    Status s;
    Card c1, c2, c3, c4, c;
    for (int i = 0; i < n; i++)
    {
        cin >> s >> c1 >> c2 >> c3 >> c4;
        roles[i] = Role(s, i, c1, c2, c3, c4);
        if (s == FP)
            FP_cnt++;
    }
    while (m--)
    {
        cin >> c;
        card_heap.push_back(c);
    }
    reverse(begin(card_heap), end(card_heap));
}

void game_on()
{
    int i = 0;
    while (true)
    {
        roles[i].get_card(2);
        roles[i].play_stage();
        i = next_role(i);
    }
}

void game_terminate(Status winner)
{
    if (winner == MP)
        cout << "MP\n";
    else
        cout << "FP\n";
    for (int i = 0; i < n; i++)
    {
        if (roles[i].health_point == 0)
            cout << "DEAD\n";
        else
        {
            auto p = roles[i].hand_card_list.begin();
            for (int j = 0; j < roles[i].hand_card_list.size(); ++j, ++p)
                cout << *p << (j < roles[i].hand_card_list.size() - 1 ? ' ' : '\n');
            if (roles[i].hand_card_list.empty())
                cout << '\n';
        }
    }
    exit(0);
}
2020/8/9 20:50
加载中...