列表

详情


NC20664. 炉石传说

描述

炉石传说是一款非常丢人的氪金游戏(卡牌游戏),现在要求你在一定程度上还原对局中的场景。
每个玩家都有随从,随从会在你面前一字排开,为了简化情况,本题只需要讨论你的随从,随从都具有攻击力与当前生命值和最大生命值,如果随从的当前生命值小于等于0,该随从死亡,且光环失效,该随从从队列中消失,随从的当前生命值无法超过最大生命值,有的随从会具有攻击光环和生命光环(光环提供给除自己以外所有随从),光环可以无限制叠加,以下是光环描述:
光环叠加:光环之间互相独立计算
得到攻击光环:得到对应数量的攻击力
得到生命光环:得到对应数量的最大生命值和当前生命值
失去攻击光环:失去对应数量的攻击力
失去生命光环:失去对应数量的最大生命值,当前生命值不会下降,但会受到最大生命值的影响
现在用事件来描述场景:
事件1:
随从入场,一行中输入五个正整数,分别表示随从攻击力,随从血量,攻击光环数值,生命光环数值,入场位置(表示从左到右数的第几个位置,如果该位置已有随从,则插到这个随从左边)
事件2:
计算你的全体随从攻击力之和,无额外描述
事件3:
对一个随从造成伤害,一行中输入两个正整数,分别表示伤害额度和随从位置(表示从左到右数的第几个随从)
事件4;
使一个随从的光环失效,但该随从依旧享受其他随从的光环,一行中输入一个正整数,表示随从位置(表示从左到右数的第几个随从)
事件5:
对所有随从造成伤害,一行中输入一个正整数,表示伤害额度
事件1到5对应输入描述中的事件序号
事件2中在一行里输出攻击力总和,其他事件不需要输出。
本题的所有数字范围都在1到1000以内,本题保证事件1,3,4描述的位置合法

输入描述

第一行一个正整数T(1<=T<=100)表示样例个数,每个样例第一行一个正整数Q(1<=Q<=1000),表示你要处理的事件个数,然后Q个事件,每个事件在第一行输入一个数字,代表发生的事件序号,同一行描述事件(如果事件有描述),事件描述中出现的数字范围都在1到1000以内。

输出描述

每当事件2发生时,在一行中输出攻击力之和。

示例1

输入:

3
3
2
1 5 5 5 5 1
2
5
1 5 5 5 5 1
1 4 4 5 5 1
2
5 9
2
6
1 5 5 5 5 1
2
1 5 5 5 5 1
2
1 5 5 5 5 1
2

输出:

0
5
19
5
5
20
45

说明:

第一个样例里,随从变化为:

无->(5/5)

第二个样例里,随从变化为:

无->(5/5)->(9/9,10/10)->(5/1)

第三个样例里,随从变化为:

无->(5/5)->(10/10,10/10)->(15/15,15/15,15/15)

原站题解

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

C++11(clang++ 3.9) 解法, 执行用时: 75ms, 内存消耗: 616K, 提交时间: 2020-03-24 21:08:34

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define ROF(i,a,b) for(int i=a;i>=b;i--)
const int MAXN=1e3+5;
struct num
{
	int att,heal,max,ar,hr;
 }a[MAXN],t;
int n,m,T,Q,cnt,ar,hr,b[10];
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		cnt=0,ar=0,hr=0;
		scanf("%d",&Q);
		while(Q--)
		{
			scanf("%d",&n);
			if(n==1)
			{
				FOR(i,1,5) scanf("%d",&b[i]);
				ar+=b[3],hr+=b[4];
				ROF(i,cnt+1,b[5]+1)
				{
					a[i]=a[i-1];
				}
				cnt++;
				a[b[5]].att=b[1];
				a[b[5]].heal=b[2];
				a[b[5]].max=b[2];
				a[b[5]].ar=b[3];
				a[b[5]].hr=b[4];
			}
			else if(n==2)
			{
				int ans;
				if(cnt!=0)
				{
					ans=ar*(cnt-1);
					FOR(i,1,cnt) ans+=a[i].att; 
				}
				else
				ans=0;
				cout<<ans<<endl;
			}
			else if(n==3)
			{
				scanf("%d%d",&n,&m);
				a[m].heal-=n;
				if(a[m].heal+hr-a[m].hr<=0)
				{
					t=a[m];
					FOR(i,m,cnt-1)
					a[i]=a[i+1];
					cnt--;
					ar-=t.ar,hr-=t.hr;
					FOR(i,1,cnt)
					a[i].heal=min(a[i].heal+t.hr,a[i].max);
				}
			}
			else if(n==4)
			{
				scanf("%d",&n);
				ar-=a[n].ar,hr-=a[n].hr;
				FOR(i,1,cnt)
				if(i!=n)
				a[i].heal=min(a[i].heal+a[n].hr,a[i].max);
				a[n].ar=0,a[n].hr=0;
			}
			else
			{
				int vis[cnt+5],m=0,p;
				memset(vis,0,sizeof(vis));
				scanf("%d",&n);
				FOR(i,1,cnt)
				{
					a[i].heal-=n;
					if(a[i].heal+hr-a[i].hr<=0)
					{
						vis[i]=1;
						m+=a[i].hr;
					 } 
				}
				p=cnt;
				cnt=0;
				FOR(i,1,p)
				if(vis[i]==0)
				{
					a[++cnt]=a[i];
					a[cnt].heal=min(a[i].heal+m,a[i].max);
				}
				else
				{
					hr-=a[i].hr;
					ar-=a[i].ar;
				}
			}
		 } 
	}
}

上一题