试题编号:
|
201609-3 |
---|---|
试题名称: | 炉石传说 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述《炉石传说:魔兽英雄传》(Hearthstone: Heroes of Warcraft,简称炉石传说)是暴雪娱乐开发的一款集换式卡牌游戏(如下图所示)。游戏在一个战斗棋盘上进行,由两名玩家轮流进行操作,本题所使用的炉石传说游戏的简化规则如下:
输入格式输入第一行是一个整数 n,表示操作的个数。接下来 n 行,每行描述一个操作,格式如下:<action> <arg1> <arg2> … 其中<action>表示操作类型,是一个字符串,共有 3 种:summon表示召唤随从,attack表示随从攻击,end表示结束回合。这 3 种操作的具体格式如下:
输出格式输出共 5 行。第 1 行包含一个整数,表示这 n 次操作后(以下称为 T 时刻)游戏的胜负结果,1 表示先手玩家获胜,-1 表示后手玩家获胜,0 表示游戏尚未结束,还没有人获胜。 第 2 行包含一个整数,表示 T 时刻先手玩家的英雄的生命值。 第 3 行包含若干个整数,第一个整数 p 表示 T 时刻先手玩家在战场上存活的随从个数,之后 p 个整数,分别表示这些随从在 T 时刻的生命值(按照从左往右的顺序)。 第 4 行和第 5 行与第 2 行和第 3 行类似,只是将玩家从先手玩家换为后手玩家。 样例输入8summon 1 3 6 summon 2 4 2 end summon 1 4 5 summon 1 2 1 attack 1 2 end attack 1 1 样例输出030 1 2 30 1 2 评测用例规模与约定 |
思路:
刚看到这道题的时候就被这道题的题目量吓到了,但是细读之后感觉还好,首先题目中所有的序号变化(召唤随从,删除随从)都可以通过vector来实现。为了输入空格、回车、字符串、数字的方便,统一用字符串输入,所以最后又用到了字符串转换数字atoi(str.c_str()); |
以下是满分代码实现
#include <bits/stdc++.h>
using namespace std;
int n;
bool judge = true; //judge为true是玩家1执行命令,judge为false是玩家2执行命令
struct node{
int att; //攻击
int heal; //生命
}aa[1005],bb[1005];
vector<node> a,b; //玩家1和玩家2
int main(){
cin >> n;
cin.get(); //吃掉回车符
string action;
/*
因为随从下标从1开始,所以下标0存储英雄角色
*/
aa[0].att = 0;aa[0].heal = 30;
bb[0].att = 0;bb[0].heal = 30;
a.push_back(aa[0]);
b.push_back(bb[0]);
/*
进行存储和判别
*/
for(int i = 1; i <= n; i++){
/*
为了解决字符串和数字以及空格类型(回车、空格等)之间的输入,直接都是字符串
以回车结束getline(cin,action);
以空格断开line >> 变量;
*/
getline(cin,action);
istringstream line(action);
line >> action;
if(action == "summon"){
string p,att,heal;
int p1,att1,heal1;
line >> p >> att >> heal;
/*
通过atoi(str.c_str())将字符串转换为数字类型
*/
p1 = atoi(p.c_str());
att1 = atoi(att.c_str());
heal1 = atoi(heal.c_str());
if(judge){ //玩家1操作
int j = a.size();
aa[j].att = att1;
aa[j].heal = heal1;
a.insert(a.begin()+p1,aa[j]);
}else{ //玩家2操作
int j = b.size();
bb[j].att = att1;
bb[j].heal = heal1;
b.insert(b.begin()+p1,bb[j]);
}
}else if(action == "end"){ //一个玩家结束,另一个玩家开始,取反
judge = !judge;
}else if(action == "attack"){ //某个玩家主杀
string att1,att2;
int attr1, attr2;
line >> att1 >> att2;
attr1 = atoi(att1.c_str());
attr2 = atoi(att2.c_str());
/*
如果为玩家2操作杀戮,第一个输入的是玩家2的随从的坐标,调换一下
*/
if(!judge){
int temp = attr1;
attr1 = attr2;
attr2 = temp;
}
/*
杀戮之后进行玩家1话玩家2的随从的生命值计算存储
*/
b[attr2].heal -= a[attr1].att;
a[attr1].heal -= b[attr2].att;
/*
某个玩家的随从生命<=0时,已死,删除,
attr2 != 0是如果英雄死了,不应该删除英雄
*/
if(b[attr2].heal <= 0 && attr2 != 0){
b.erase(b.begin()+attr2);
}
if(a[attr1].heal <= 0 && attr1 != 0){
a.erase(a.begin()+attr1);
}
}
if(a[0].heal <= 0 || b[0].heal <= 0){
break;
}
}
/*
当时脑子抽风了,竟然写了个cout << a[0].heal-b[0].heal << endl;
导致只有70分,我差点疯了,啊啊啊啊啊啊啊啊啊啊啊啊啊!!!!!!!!!
*/
if(a[0].heal <= 0){
cout << "-1\n";
}else if(b[0].heal <= 0){
cout << "1\n" ;
}else{
cout << "0\n";
}
cout << a[0].heal << "\n" << a.size()-1 << " " ;
for(int i = 1; i < a.size(); i++){
cout << a[i].heal << " ";
}
cout << "\n" << b[0].heal << "\n" << b.size()-1 << " ";
for(int i = 1; i < b.size(); i++){
cout << b[i].heal << " ";
}
return 0;
}