題目描述:
《爐石傳說:魔獸英雄傳》(Hearthstone: Heroes of Warcraft,簡稱爐石傳說)是暴雪娛樂開發的一款集換式卡牌遊戲(如下圖所示)。遊戲在一個戰鬥棋盤上進行,由兩名玩家輪流進行操作,本題所使用的爐石傳說遊戲的簡化規則如下:
* 玩家會控制一些角色,每個角色有自己的生命值和攻擊力。當生命值小于等于 0 時,該角色死亡。角色分為英雄和随從。
* 玩家各控制一個英雄,遊戲開始時,英雄的生命值為 30,攻擊力為 0。當英雄死亡時,遊戲結束,英雄未死亡的一方獲勝。
* 玩家可在遊戲過程中召喚随從。棋盤上每方都有 7 個可用于放置随從的空位,從左到右一字排開,被稱為戰場。當随從死亡時,它将被從戰場上移除。
* 遊戲開始後,兩位玩家輪流進行操作,每個玩家的連續一組操作稱為一個回合。
* 每個回合中,目前玩家可進行零個或者多個以下操作:
1) 召喚随從:玩家召喚一個随從進入戰場,随從具有指定的生命值和攻擊力。
2) 随從攻擊:玩家控制自己的某個随從攻擊對手的英雄或者某個随從。
3) 結束回合:玩家聲明自己的目前回合結束,遊戲将進入對手的回合。該操作一定是一個回合的最後一個操作。
* 當随從攻擊時,攻擊方和被攻擊方會同時對彼此造成等同于自己攻擊力的傷害。受到傷害的角色的生命值将會減少,數值等同于受到的傷害。例如,随從 X 的生命值為 HX、攻擊力為 AX,随從 Y 的生命值為 HY、攻擊力為 AY,如果随從 X 攻擊随從 Y,則攻擊發生後随從 X 的生命值變為 HX - AY,随從 Y 的生命值變為 HY - AX。攻擊發生後,角色的生命值可以為負數。
本題将給出一個遊戲的過程,要求編寫程式模拟該遊戲過程并輸出最後的局面。
input:
輸入第一行是一個整數 n,表示操作的個數。接下來 n 行,每行描述一個操作,格式如下:
<action> <arg1> <arg2> ...
其中<action>表示操作類型,是一個字元串,共有 3 種:summon表示召喚随從,attack表示随從攻擊,end表示結束回合。這 3 種操作的具體格式如下:
* summon <position> <attack> <health>:目前玩家在位置<position>召喚一個生命值為<health>、攻擊力為<attack>的随從。其中<position>是一個 1 到 7 的整數,表示召喚的随從出現在戰場上的位置,原來該位置及右邊的随從都将順次向右移動一位。
* attack <attacker> <defender>:目前玩家的角色<attacker>攻擊對方的角色 <defender>。<attacker>是 1 到 7 的整數,表示發起攻擊的本方随從編号,<defender>是 0 到 7 的整數,表示被攻擊的對方角色,0 表示攻擊對方英雄,1 到 7 表示攻擊對方随從的編号。
* end:目前玩家結束本回合。
注意:随從的編号會随着遊戲的程序發生變化,當召喚一個随從時,玩家指定召喚該随從放入戰場的位置,此時,原來該位置及右邊的所有随從編号都會增加 1。而當一個随從死亡時,它右邊的所有随從編号都會減少 1。任意時刻,戰場上的随從總是從1開始連續編号。
output:
輸出共 5 行。
第 1 行包含一個整數,表示這 n 次操作後(以下稱為 T 時刻)遊戲的勝負結果,1 表示先手玩家獲勝,-1 表示後手玩家獲勝,0 表示遊戲尚未結束,還沒有人獲勝。
第 2 行包含一個整數,表示 T 時刻先手玩家的英雄的生命值。
第 3 行包含若幹個整數,第一個整數 p 表示 T 時刻先手玩家在戰場上存活的随從個數,之後 p 個整數,分别表示這些随從在 T 時刻的生命值(按照從左往右的順序)。
第 4 行和第 5 行與第 2 行和第 3 行類似,隻是将玩家從先手玩家換為後手玩家。
思路:
模拟題,難度并不大,主要考察玩家随從的存儲以及随從的增加、删除操作。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int id,win=-1;//0表示玩家1,1表示玩家2
string s;
struct node
{
int blood=30;
int sum;
int attack[9];
int health[9];
void put(int pos,int a,int h)
{
if(pos==sum+1)
{
attack[++sum]=a;
health[sum]=h;
}
else
{
for(int i=7;i>pos;i--)
{
attack[i]=attack[i-1];
health[i]=health[i-1];
}
attack[pos]=a;
health[pos]=h;
sum++;
}
}
void del()
{
int flag=-1;
for(int i=1;i<=sum;i++)
if(health[i]<=0)
flag=i;
if(flag==7)
{
sum--;
health[flag]=0;
attack[flag]=0;
return;
}
else if(flag==-1) return;
for(int i=flag;i<=7;i++)
{
health[i]=health[i+1];
attack[i]=attack[i+1];
}
sum--;
}
}a[2];
void atk(int id,int at,int de)
{
if(de==0)
{
a[1-id].blood-=a[id].attack[at];
if(a[1-id].blood<=0)
{
win=id;
}
return;
}
a[id].health[at]-=a[1-id].attack[de];
a[1-id].health[de]-=a[id].attack[at];
a[id].del();
a[1-id].del();
}
void output()
{
if(win==-1) cout<<0;
else if(win==0) cout<<1;
else if(win==1) cout<<-1;
cout<<endl;
cout<<a[0].blood<<endl<<a[0].sum<<" ";
for(int i=1;i<=a[0].sum;i++)
cout<<a[0].health[i]<<" ";
cout<<endl;
cout<<a[1].blood<<endl<<a[1].sum<<" ";
for(int i=1;i<=a[1].sum;i++)
cout<<a[1].health[i]<<" ";
}
int main()
{
int n,x,y,z;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>s;
if(s=="summon")
{
cin>>x>>y>>z;
a[id].put(x,y,z);
}
else if(s=="attack")
{
cin>>x>>y;
atk(id,x,y);
}
else if(s=="end") id=1-id;
}
output();
return 0;
}