社区讨论
为什么代码厌氧
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 条回复,欢迎继续交流。
正在加载回复...