NC20664. 炉石传说
描述
输入描述
第一行一个正整数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
说明:
第一个样例里,随从变化为: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; } } } } }