列表

详情


NC216202. JiubeiAndHearthstoneBattlegrounds

描述

喜欢上课摸鱼,《炉石传说∙酒馆战棋》是他最喜欢玩的移动端游戏之一。
这是一个双人对战游戏,每名玩家拥有若干个随从,每名玩家拥有的随从在战场上分别从左至右排成一行(如上图所示)。
随从是一种具有攻击力、生命值和若干关键字的一种单位。每个关键字代表着这个随从的一项特殊能力。
当随从 A 攻击随从 B 时,随从 B 会受到相当于随从 A 的攻击力的伤害(减少等量的生命值),同时随从 A 也会受到相当于 B 的攻击力的伤害。如果一个随从的生命值不大于 0,那它就会死亡,死亡的随从会被移出战场。
两名玩家轮流进行回合,并且 是先行动的一方。
对于本题,不同于真实游戏,每一回合,当前回合玩家所拥有的处于战场最左边的随从会攻击对方拥有的处于战场最左边的随从,在这之后,轮到对手行动。直到一名玩家拥有的随从全部死亡,游戏结束。
随从们可能会拥有以下关键字的一个或多个:
  • 嘲讽(Taunt):敌方随从会优先攻击这个随从而不是战场最左侧的随从,如果有多个嘲讽随从,则攻击战场最左侧的嘲讽随从。
  • 圣盾(Divine Shield):拥有圣盾的随从会免疫其受到的一次伤害,然后失去圣盾
  • 复生(Reborn):具有复生关键字的随从在首次死亡时会回到战场(置于原位),并具有 1 点生命值以及游戏开始时其拥有的所有关键字。
  • 剧毒(Poisonous):当一个具有剧毒的随从造成未被免疫的伤害时,受到这个伤害的随从会立即死亡。
  • 亡语(DeathRattle(x,y,z)): 当具有亡语的随从死亡时,会召唤 个攻击力为 ,生命值为 的随从,这些随从会被依次召唤到战场最右侧,且不具有任何关键字。
注意:如果一个随从同时具有复生亡语,则在它触发复生效果前会触发其亡语。

输入描述

输入的第一行包含两个非负整数  表示 jiubei 和他的对手分别拥有几个随从。
接下来的 行按照从左至右的顺序给出了jiubei 拥有的随从的信息。每一行包含一个随从的信息,表示方式如下:
Taunt Reborn... 是这个随从的攻击力, 是这个随从的生命值,随后是这个随从所具有的关键字。
接下来的 行按照从左至右的顺序给出了 jiubei 的对手拥有的随从的信息,表示方式同上。
输入保证 ,并且对于一个随从不会出现多个同样的关键字。
如果你依旧不能理解题目内容,可以参考输入样例。

输出描述

你需要输出战斗结束时战场上的随从信息。
第一行是场上所剩余的随从数量。
接下来按照从左到右的顺序,每行输出一个随从的攻击力和生命值,格式为

示例1

输入:

1 2
2/5
1/1 Reborn Divine Shield
2/2 Poisonous Taunt DeathRattle(1,1,2) Reborn

输出:

4
1/1
2/1
1/1
1/1

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C(clang11) 解法, 执行用时: 2ms, 内存消耗: 504K, 提交时间: 2020-12-26 23:39:20

#include <stdio.h>
#include <string.h>
int taunt_test(int);
int first_test(int);
void read();
void battle();

int hand = 0, cnt[2], winner = -1;
struct dt {
	long long int harm, health, taunt, divine_shield, divine_shield_backup, reborn, poisonous, death_rattle[3];
} d[2][1200], dr;

void read() {
	char ch, s[50];
	memset(dr.death_rattle, 0, sizeof(dr.death_rattle));
	dr.divine_shield = dr.divine_shield_backup = dr.poisonous = dr.reborn = dr.taunt = 0;
	scanf("%lld/%lld", &dr.harm, &dr.health);
	while (1) {
		ch = getchar();
		if (ch == '\n')
			return;
		else {
			scanf("%s", s);
			if (strcmp(s, "Taunt") == 0)
				dr.taunt = 1;
			else if (strcmp(s, "Divine") == 0) {
				dr.divine_shield_backup = dr.divine_shield = 1;
				scanf("%s", s);
			} else if (strcmp(s, "Reborn") == 0)
				dr.reborn = 1;
			else if (strcmp(s, "Poisonous") == 0)
				dr.poisonous = 1;
			else {
				sscanf(s, "DeathRattle(%lld,%lld,%lld)", &dr.death_rattle[0], &dr.death_rattle[1], &dr.death_rattle[2]);
			}
		}
	}
}

void battle() {
	int first_taust = taunt_test(!hand), target, attacker, i;
	target = first_test(!hand);
	attacker = first_test(hand);
	if (target == -1) {
		winner = hand;
		return;
	}
	if (attacker == -1) {
		winner = !hand;
		return;
	}
	if (first_taust != -1)
		target = first_taust;
	if (d[!hand][target].divine_shield)
		d[!hand][target].divine_shield = 0;
	else {
		d[!hand][target].health -= d[hand][attacker].harm;
		if (d[hand][attacker].poisonous)
			d[!hand][target].health = 0;
	}
	if (d[hand][attacker].divine_shield)
		d[hand][attacker].divine_shield = 0;
	else {
		d[hand][attacker].health -= d[!hand][target].harm;
		if (d[!hand][target].poisonous)
			d[hand][attacker].health = 0;
	}
	if (d[!hand][target].health <= 0) {
		if (d[!hand][target].death_rattle[2]) {
			for (i = 0; i < d[!hand][target].death_rattle[2]; ++i) {
				d[!hand][cnt[!hand]].harm = d[!hand][target].death_rattle[0];
				d[!hand][cnt[!hand]].health = d[!hand][target].death_rattle[1];
				++cnt[!hand];
			}
		}
		if (d[!hand][target].reborn) {
			d[!hand][target].health = 1;
			d[!hand][target].reborn = 0;
			d[!hand][target].divine_shield = d[!hand][target].divine_shield_backup;
		}
	}
	if (d[hand][attacker].health <= 0) {
		if (d[hand][attacker].death_rattle[2]) {
			for (i = 0; i < d[hand][attacker].death_rattle[2]; ++i) {
				d[hand][cnt[hand]].harm = d[hand][attacker].death_rattle[0];
				d[hand][cnt[hand]].health = d[hand][attacker].death_rattle[1];
				++cnt[hand];
			}
		}
		if (d[hand][attacker].reborn) {
			d[hand][attacker].health = 1;
			d[hand][attacker].reborn = 0;
			d[hand][attacker].divine_shield = d[hand][attacker].divine_shield_backup;
		}
	}
	hand = !hand;
}

int taunt_test(int p) {
	int i;
	for (i = 0; i < cnt[!hand]; ++i) {
		if (d[p][i].health <= 0)
			continue;
		if (d[p][i].taunt)
			return i;
	}
	return -1;
}

int first_test(int p) {
	int i;
	for (i = 0; i < cnt[p]; ++i) {
		if (d[p][i].health > 0)
			return i;
	}
	return -1;
}

main() {
	int n, m, i, left;
	memset(d, 0, sizeof(d));
	scanf("%d%d", &n, &m);
	for (i = 0; i < n; ++i) {
		read();
		d[0][i] = dr;
	}
	for (i = 0; i < m; ++i) {
		read();
		d[1][i] = dr;
	}
	cnt[0] = n;
	cnt[1] = m;
	while (winner == -1)
		battle();
	left = 0;
	for (i = 0; i < cnt[winner]; ++i)
		if (d[winner][i].health > 0)
			++left;
	printf("%d\n", left);
	for (i = 0; i < cnt[winner]; ++i)
		if (d[winner][i].health > 0)
			printf("%d/%d\n", d[winner][i].harm, d[winner][i].health);
}

C++(clang++11) 解法, 执行用时: 6ms, 内存消耗: 6652K, 提交时间: 2020-12-26 18:07:32

#include <bits/stdc++.h>
#define pb push_back
#define F(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
const int N=100010;
int n,m;
bool gameOver;
vector<pair<int,int>> ans;
struct servant{
    int x,y,sa=0,sb=0,sc=0;
    bool tT=0,tDS=0,tR=0,tP=0,tDR=0;
    bool T=0,DS=0,R=0,P=0,DR=0;
    void read(){
        string s;
        cin>>s;
        x=atoi(s.substr(0,s.find("/")).c_str());
        y=atoi(s.substr(s.find("/")+1).c_str());
        getline(cin,s);
        stringstream ss;
        ss<<s;
        while(ss>>s){
            if(s=="Reborn")tR=R=1;
            if(s=="Divine")ss>>s,tDS=DS=1;
            if(s=="Poisonous")tP=P=1;
            if(s=="Taunt")tT=T=1;
            if(s.find("(")!=s.npos){
                int l,m=0,r,a,b,c;
                for(int i=0;i<s.size();i++){
                    if(s[i]=='(')l=i;
                    if(!m&&s[i]==',')m=i;
                    if(i!=m&&s[i]==',')r=i;
                }
                sa=atoi(s.substr(l+1).c_str());
                sb=atoi(s.substr(m+1).c_str());
                sc=atoi(s.substr(r+1).c_str());
                tDR=DR=1;
            }
        }
    }
}a[N],b[N];
void death(servant a[],int id,int f){
    if(a[id].tDR){
        servant t;
        t.x=a[id].sa,t.y=a[id].sb;
        F(i,1,a[id].sc)a[f?++n:++m]=t;
        a[id].tDR=0;
    }
    if(a[id].tR){
        a[id].y=1,a[id].tDS=a[id].DS;
        a[id].tDR=a[id].DR;
        a[id].tR=0;
    }
}
void battle(){
    int ia=0,ib=0;
    F(i,1,n)if(a[i].y){ia=i;break;}
    F(i,1,m)if(b[i].tT&&b[i].y){ib=i;break;}
    if(!ib)F(i,1,m)if(b[i].y){ib=i;break;}
    if(!ia||!ib){gameOver=1;return;}
    if(b[ib].tDS)b[ib].tDS=0;
    else{
        b[ib].y=max(b[ib].y-(a[ia].P?1000:a[ia].x),0);
        if(!b[ib].y)death(b,ib,0);
    }
    if(a[ia].tDS)a[ia].tDS=0;
    else{
        a[ia].y=max(a[ia].y-(b[ib].P?1000:b[ib].x),0);
        if(!a[ia].y)death(a,ia,1);
    }
    ia=0,ib=0;
    F(i,1,m)if(b[i].y){ib=i;break;}
    F(i,1,n)if(a[i].tT&&a[i].y){ia=i;break;}
    if(!ia)F(i,1,n)if(a[i].y){ia=i;break;}
    if(!ia||!ib){gameOver=1;return;}
    if(a[ia].tDS)a[ia].tDS=0;
    else{
        a[ia].y=max(a[ia].y-(b[ib].P?1000:b[ib].x),0);
        if(!a[ia].y)death(a,ia,1);
    }
    if(b[ib].tDS)b[ib].tDS=0;
    else{
        b[ib].y=max(b[ib].y-(a[ia].P?1000:a[ia].x),0);
        if(!b[ib].y)death(b,ib,0);
    }
}
int main(){
    cin>>n>>m;
    F(i,1,n)a[i].read();
    F(i,1,m)b[i].read();
    while(!gameOver)battle();
    F(i,1,n)if(a[i].y)ans.pb({a[i].x,a[i].y});
    F(i,1,m)if(b[i].y)ans.pb({b[i].x,b[i].y});
    cout<<ans.size()<<"\n";
    for(auto i:ans)cout<<i.first<<"/"<<i.second<<"\n";
}

上一题