题目描述
输入输出
样例
Hints
思路
因为英雄和随从都有多个属性,分别定义英雄和随从类
- 英雄类:包括生命值,随从数组,随从数目,以及召唤随从函数add()和随从被攻击函数dmg()
- 随从类:包括生命值和攻击力
英雄数组中play0代表先手玩家,player1代表后手玩家
进行n次操作,now=0代表先手玩家的回合,now=1代表后手玩家的回合,通过与1异或来循环操作
根据操作种类,分别进行以下3种操作:
- 召唤随从:如果该随从的位置编号小于目前玩家随从的总数,则需要将该编号及以后的随从向后移动一位,向后移动过程应逆向进行,从最后一个随从开始。
- 随从攻击:如果己方随从攻击对方的随从,对两方的相关随从分别扣血(扣血量等于对方攻击力),如果该随从被攻击后死亡(生命值小于等于0),该随从位置后面的随从位置前移1;如果攻击对方英雄,则对方英雄直接扣血即可。
- 回合结束:now与1异或,0号玩家和1号玩家交替行动
n个操作结束后,判断两方英雄的生死,输出需要的结果即可。
注意
这道题不是很复杂,根据题意依次写执行代码就能解决,这道题通过对每个玩家结构体用了类似class的封装,为对不同玩家属性值的操作带来了极大简便,很有学习意义。(ps:也让我了解了一下炉石的规则^ - ^)
代码
#include<iostream>
#include<cstdio>
using namespace std;
struct Ent{
int health,attack;
Ent() {}
Ent(int h,int a) {
health=h,attack=a;
}
};
struct Hero{
int life=30;
Ent card[10];
int num=0;
Hero() {}
void add(int p,Ent e) {
num++;
for(int i=num;i>p;i--)
card[i]=card[i-1];
card[p]=e;
}
void dmg(int p,int a) {
card[p].health-=a;
if(card[p].health<=0) {
for(int i=p;i<num;++i)
card[i]=card[i+1];
num--;
}
}
}play[2];
int n,now;
string cmd;
int main() {
cin>>n;
int p,a,h,d;
while(n--) {
cin>>cmd;
if(cmd=="summon") {
cin>>p>>a>>h;
play[now].add(p,Ent(h,a));
}else if(cmd=="attack") {
cin>>a>>d;
if(d==0) play[now^1].life-=play[now].card[a].attack;
else {
int a1=play[now].card[a].attack;
int a2=play[now^1].card[d].attack;
play[now].dmg(a,a2);
play[now^1].dmg(d,a1);
}
}else if(cmd=="end") {
now^=1;
}
}
if(play[0].life<=0) cout<<-1<<endl;
else if(play[1].life<=0) cout<<1<<endl;
else cout<<0<<endl;
cout<<play[0].life<<"\n"<<play[0].num;
for(int i=1;i<=play[0].num;++i)
cout<<" "<<play[0].card[i].health;
cout<<endl;
cout<<play[1].life<<"\n"<<play[1].num;
for(int i=1;i<=play[1].num;++i)
cout<<" "<<play[1].card[i].health;
cout<<endl;
return 0;
}