社区讨论

为什么代码厌氧

P2482[SDOI2010] 猪国杀参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@loa2nuhe
此快照首次捕获于
2023/10/28 21:22
2 年前
此快照最后确认于
2023/11/02 11:00
2 年前
查看原帖

开O2,45pts

关O2,100pts

代码如下(把调试注释删了,好看些)
CPP
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#include<string>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;

char getcdc()
{
    char c = getchar();
    while(c < 'A' || c > 'Z') c = getchar();
    return c;
}

int typec(char name);
int typep(string ch);
void gaming();
int gameover();
void input();
void output(int winner);

int n, m, nmMP, nmZP, nmFP, Mip;
bool gameoverflag = false;

struct Card{
    char name;
    int tp; //0代表杀,1代表闪,2代表桃,3代表决斗,4代表南猪入侵,5代表万箭齐发,6代表无懈可击,7代表诸葛连弩
    Card(char nm): name(nm), tp(typec(nm)){}
    void IO_print(){printf("%c ", name);}
};

struct Player{
    vector<Card> cds;
    string ch;
    int tp;              //0代表主猪, 1代表忠猪, 2代表反猪
    int rl;              //-1未表身份, 0表示主猪, 1代表跳忠猪, 2代表跳反猪, 3代表类反猪
    int hp = 4;          //血量
    int ip;              //当前猪编号
    int lasip;           //上个猪编号
    int nxtip;           //下个猪编号
    int htip;            //伤害来源
    int nmk;         //一回合已使用的杀
    bool life = true;    //生命状态
    bool liannu = false; //诸葛连弩状态值
    // CARD_代表牌堆操作,DETE_代表检测类操作(状态与手牌),PLAY_表示出牌操作,RESP_表示回应操作
    void CARD_orignal(char c1, char c2, char c3, char c4);
    void CARD_get(int k);
    bool CARD_play(int type);
    bool DETE_wuxie(int fip, int tip, int crd);
    bool DETE_kill();
    bool DETE_peach(int sit);
    bool DETE_death();
    int DETE_battle();
    bool PLAY_kill();
    bool PLAY_peach(int sit);
    bool PLAY_jinnang(int tip, int crd);
    bool PLAY_nanman();
    bool PLAY_wanjian();
    bool PLAY_battle();
    bool PLAY_wuxie(int fip, int tip, int crd);
    bool PLAY_liannu();
    void RESP_kill(int fip);
    void RESP_battle(int fip);
    void RESP_nanman(int fip);
    void RESP_wanjian(int fip);
    void ROUND();
};

queue<Card> card_heap;
vector<Player> player_list;

int main()
{
    input();
    gaming();
    return 0;
}

void gaming()
{
    int pip = Mip;
    while(!gameoverflag){
        player_list[pip].ROUND();
        pip = player_list[pip].nxtip;
    }
    return;
}

int gameover()
{
    if(nmFP == 0){
        output(0);
        gameoverflag = 1;
        return 1;
    }
    if(nmMP == 0){
        output(1);
        gameoverflag = 1;
        return 2;
    }
    return 0;
}

void input()
{
    cin >> n >> m;
    Player pig;
    player_list.push_back(pig);
    for(int i = 1; i <= n; i++){
        string type;
        type += getcdc();
        type += getcdc();
        if(typep(type) == 0) Mip = i, nmMP++;
        else if(typep(type) == 1) nmZP++;
        else nmFP++;
        player_list.push_back(pig);
        player_list[i].tp = typep(type); 
        player_list[i].rl = (typep(type) == 0) ? 0 : -1; 
        player_list[i].ip = i; 
        player_list[i].lasip = (i == 1) ? n : i - 1; 
        player_list[i].nxtip = (i == n) ? 1 : i + 1;
        char c1, c2, c3, c4;
        c1 = getcdc(), c2 = getcdc(), c3 = getcdc(), c4 = getcdc();
        player_list[i].CARD_orignal(c1, c2, c3, c4);
    }
    for(int i = 1; i <= m; i++){
        char c;
        c = getcdc();
        Card cd(c);
        card_heap.push(cd);
    }
}

void output(int winner)
{
    if(winner == 0) printf("MP\n");
    else printf("FP\n");
    for(int i = 1; i <= n; i++){
        if(player_list[i].life == false) 
            printf("DEAD\n");
        else{
            for(auto cdi : player_list[i].cds)
                cdi.IO_print();
            printf("\n");
        }
    }
}

int typec(char name)
{ //卡牌名转数字
    switch (name){
        case 'K': return 0;
        case 'D': return 1;
        case 'P': return 2;
        case 'F': return 3;
        case 'N': return 4;
        case 'W': return 5;
        case 'J': return 6;
        case 'Z': return 7;
    }
    return -1;
}

int typep(string ch)
{ //猪猪角色转序号
    if(ch == "MP") return 0;
    if(ch == "ZP") return 1;
    if(ch == "FP") return 2;
    return -1;
}
void Player::ROUND()
{
    bool flag = true;
    nmk = 0;
    CARD_get(2);
    while(flag){
        flag = false;
        for(int i = 0; i < cds.size(); i++){
            int cdit = cds[i].tp;
            if(cdit == 0) {
                if(PLAY_kill()) flag = true;}
            else if(cdit == 2){
                if(PLAY_peach(0)) flag = true;}
            else if(cdit == 3){
                if(PLAY_battle()) flag = true;}
            else if(cdit == 4){
                if(PLAY_nanman()) flag = true;}
            else if(cdit == 5) {
                if(PLAY_wanjian()) flag = true;}
            else if(cdit == 7) {
                if(PLAY_liannu()) flag = true;}
            if(gameoverflag == 1 || life == 0) return;
            if(flag == true) break;
        }
        if(gameoverflag == 1) return;
    }
    return;
}

void Player::CARD_orignal(char c1, char c2, char c3, char c4)
{ //获得原始牌
    Card cd1(c1), cd2(c2), cd3(c3), cd4(c4);
    cds.push_back(cd1);
    cds.push_back(cd2);
    cds.push_back(cd3);
    cds.push_back(cd4);
}

void Player::CARD_get(int k)
{ //摸k张牌
    for(int i = 1; i <= k; i++){
        Card pre_card = card_heap.front();
        card_heap.pop();
        if(card_heap.empty()) card_heap.push(pre_card);
        cds.push_back(pre_card);
    }
}

bool Player::CARD_play(int type)
{ //寻找需要的特定牌,如果有就返回true,同时出牌
    for(int i = 0; i < cds.size(); i++){
        if(cds[i].tp == type){
            //cout << "   CARD - " << ip << " play " << cds[i].tp << endl;
            cds.erase(cds.begin() + i);
            return true;
        }
    }
    return false;
}

bool Player::DETE_death()
{ //判定角色是否死亡,如果死亡则返回1,未死亡返回0
  //特别的,当反猪死亡时伤害来源摸三张牌,当主猪杀死忠猪时主猪弃掉所有牌;
    if(hp > 0) return 0;
    int cntp = 0;
    for(int i = 0; i < cds.size(); i++)
        if(cds[i].tp == 2) cntp++;
    if(hp + cntp > 0)
        while(hp < 1){
            if(PLAY_peach(1)) continue;
            else break;
        }
    if(hp < 1){
        life = false;
        if(tp == 0) nmMP--;
        if(tp == 1) nmZP--;
        if(tp == 2) nmFP--;
        if(gameover()){
            gameoverflag = 1;
            return true;
        }
        player_list[lasip].nxtip = nxtip;
        player_list[nxtip].lasip = lasip;
        if(tp == 1){
            if(player_list[htip].tp == 0){
                player_list[htip].cds.clear(); 
                player_list[htip].liannu = false;
            }
        }
        if(tp == 2){
            player_list[htip].CARD_get(3);
        }
        return true;
    }
    return false;
}

bool Player::DETE_kill()
{ //判断能否对下家出杀
    if(nmk > 0 && !liannu)  return false;
    if(tp == 0)
        if(player_list[nxtip].rl == 2 || player_list[nxtip].rl == 3) return true;
        else return false;
    else if(tp == 1)
        if(player_list[nxtip].rl == 2) return true;
        else return false;
    else if(player_list[nxtip].rl == 0 || player_list[nxtip].rl == 1) return true;
        else return false;
}

int Player::DETE_battle()
{ //找出能决斗的猪,并返回其编号,找不到就返回0
    if(tp == 0)
        for(int i = nxtip; i != ip; i = player_list[i].nxtip)
            if(player_list[i].rl == 2 || player_list[i].rl == 3) return i;
    if(tp == 1) 
        for(int i = nxtip; i != ip; i = player_list[i].nxtip)
            if(player_list[i].rl == 2) return i;
    if(tp == 2)
        for(int i = nxtip; i != ip; i = player_list[i].nxtip)
            if(player_list[i].rl == 0) return i;
    return 0;
}

bool Player::DETE_peach(int sit)
{ //判断能否使用桃,1为回合外用桃,需要濒死;0为回合内用桃,需要血量<4
    if(sit == 0 && hp < 4) return true; 
    else if(sit == 1) return hp <= 0;
}

bool Player::DETE_wuxie(int fip, int tip, int crd)
{ //判定此时猪猪会不会使用无懈可击,fip代表使用锦囊的猪,tip代表锦囊的对象,crd代表锦囊的类型
    if(crd == 3 || crd == 4 || crd == 5){
        if((tp == 0 || tp == 1) && (player_list[tip].rl == 0 || player_list[tip].rl == 1)) return true;
        if((tp == 2) && player_list[tip].rl == 2) return true;
    }
    if(crd == 6){
        if((tp == 0 || tp == 1) && (player_list[fip].rl == 2)) return true;
        if((tp == 2) && (player_list[fip].rl == 0 || player_list[fip].rl == 1)) return true;
    }
    return false;
}

bool Player::PLAY_kill()
{ //出杀,不能出就不出
    if(!DETE_kill()) return false;
    if(!CARD_play(0)) return false;
    player_list[nxtip].RESP_kill(ip);
    if(gameoverflag == 1) return false;
    nmk++;
    if(player_list[nxtip].rl == 2 && tp == 1) rl = 1;
    else if(player_list[nxtip].rl == 1 || player_list[nxtip].rl == 0) rl = 2;
    
    return true;
}

bool Player::PLAY_peach(int sit)
{
    if(!DETE_peach(sit)) return false;
    if(!CARD_play(2)) return false;
    hp++;
    return true;
}

/*
对于南蛮/万箭/决斗(作用在接收者上)
    主公/忠: * --锦囊--> 主公/跳忠
    反:      * --锦囊--> 跳反上

对于无懈(作用在发出者上):
    主公/忠:跳反 --锦囊-->      *
    反:     跳忠/主公 --锦囊--> *
*/

bool Player::PLAY_jinnang(int tip, int crd)
{ //在出了一个锦囊牌后,轮流判定无懈的连锁反应,应当在个PLAY_battle/wanjian/nanman/wuxie内部使用
    for(int i = ip, visi = 0;; i = player_list[i].nxtip){
        if(i == ip) visi++;
        if(visi == 2) break;
        if(player_list[i].PLAY_wuxie(ip, tip, crd) || gameoverflag == 1)
            return false;
    }
    return true;
}

bool Player::PLAY_wuxie(int fip, int tip, int crd)
{ //fip即针对的锦囊牌的使用者,tip为针对的锦囊牌的目标,crd为锦囊牌的类型
    if(!DETE_wuxie(fip, tip, crd)) return false;
    if(!CARD_play(6)) return false;
    if(tp == 1) rl = 1;
    else if(tp == 2) rl = 2;
    if(!PLAY_jinnang(fip, 6)) return false;
    return true;
}

bool Player::PLAY_battle()
{
    int tip = DETE_battle();
    if(!tip) return false;
    if(!CARD_play(3)) return false;
    if(tp == 1) rl = 1;
    if(tp == 2) rl = 2;
    if(!PLAY_jinnang(tip, 3)) return true;
    player_list[tip].RESP_battle(ip);
    if(gameoverflag == 1) return false;
    return true;
}

bool Player::PLAY_nanman()
{
    if(!CARD_play(4)) return false;
    for(int i = nxtip; i != ip; i = player_list[i].nxtip){
        if(!PLAY_jinnang(i, 4)) continue;
        player_list[i].RESP_nanman(ip);
        if(gameoverflag == 1) return false;
    }
    return true;
}

bool Player::PLAY_wanjian()
{
    if(!CARD_play(5)) return false;
    for(int i = nxtip; i != ip; i = player_list[i].nxtip){
        if(!PLAY_jinnang(i, 5)) continue;
        player_list[i].RESP_wanjian(ip);
        if(gameoverflag == 1) return false;
    }
    return true;
}

bool Player::PLAY_liannu()
{
    if(!CARD_play(7)) return false;
    liannu = true;
    return true;
}

void Player::RESP_kill(int fip)
{   
    if(CARD_play(1)) return;
    hp--;
    htip = fip;
    DETE_death();
    return;
}

void Player::RESP_battle(int fip)
{
    if(player_list[fip].rl == 0 && tp == 1){
        hp--;
        htip = fip;
        DETE_death();
        return;
    }
    else{
        int kip = ip;
        while(player_list[kip].CARD_play(0)){
            if(kip == ip) kip = fip;
            else if(kip == fip) kip = ip;
        }
        if(kip == ip){
            hp--;
            htip = fip; 
            DETE_death();
            return;
        }
        if(kip == fip){
            player_list[fip].hp--;
            player_list[fip].htip = ip; 
            player_list[fip].DETE_death();
            return;
        }
    }
}

void Player::RESP_nanman(int fip)
{
    if(CARD_play(0)) return;
    hp--;
    htip = fip;
    if(tp == 0 && player_list[fip].rl == -1) 
        player_list[fip].rl = 3;
    DETE_death();
    return;
}

void Player::RESP_wanjian(int fip)
{
    if(CARD_play(1)) return;
    hp--;
    htip = fip;
    if(tp == 0 && player_list[fip].rl == -1) 
        player_list[fip].rl = 3;
    DETE_death();
    return;    
}   

回复

2 条回复,欢迎继续交流。

正在加载回复...