题目: Monsters And Spells"/>
cf题目: Monsters And Spells
Monsters And Spells
- 题目意思
- 代码如下
题目链接
题目意思
一个战士打怪兽,每个怪兽有消失时间和血量,战士每秒可以蓄力1点,战士需要蓄力到大于等于该怪兽的血量才能消灭该怪兽,战士在每一秒可以选择继续蓄力或者是从头开始,从头开始的话,战士的的力量是1。
这道题目的思路就是从后面往前找,因为题目中给的数据是已经排好序的,所以最后面的肯定就是相对在时间轴的最右边的。我们思考下面的一个例子来引出思路:
2
5 7
5 6
可以看出 5 5 5和 7 7 7之间隔了一个 6 6 6,而 7 7 7这边的怪兽血量是6,因此我们考虑最少花费情况的话, 5 5 5这里的战士能量应该是4,但是 5 5 5这边有一个怪兽血量是5(怪兽血量比我们期望的能量值大),因此我们只能让后面 7 7 7这边也加上1,这样才能保证在 5 5 5的时候战士能够有5能量值。
上面是怪兽血量比期望的能量值大的情况,那碰到小的情况就更好做了,我们就当这里能量值就是期望值就可以了,因为这样也可以把怪兽杀死。如果在这一点的期望值是0,那说明后面的已经对这一点再往前的点没有什么影响了,我们重新开始这一过程知道第一个怪兽即可。
代码如下
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e2+5;
ll a[maxn],h[maxn];
vector<pair<ll,ll> > record;ll max(ll aa,ll bb)
{return aa>bb?aa:bb;
}void solve()
{while(!record.empty()){record.clear();}int n;scanf("%d",&n);for(int i=0;i<n;i++) scanf("%lld",&a[i]);for(int i=0;i<n;i++) scanf("%lld",&h[i]);int i=n-1;ll la=0,qi=0;ll now=i,nowc=h[i];i--;while(i>=0){la=a[now]-a[i],qi=max(0,h[now]-la);//两者之间坐标差值,预期的能量值if(qi==0){record.push_back(pair<ll,ll>(now,nowc));//vector数组相当于每次记录的是一轮中最后面那个点的时间坐标和在这一点的能量值now=i,nowc=h[i];}else if(qi<h[i]){nowc+=(h[i]-qi);//因为期望比实际的要小,所以我们更新这个值h[now]=nowc;//这里要更新h数组的值因为下一次循环的时候还要用到这个值}i--;}record.push_back(pair<ll,ll>(now,nowc));ll res=0;vector<pair<ll,ll> >::iterator it;for(it=record.begin();it!=record.end();it++){res+=((it->second*(it->second+1))/2);//计算的时候因为是从1加到了这个值,因此直接计算等差数列前n项和}printf("%lld\n",res);
}int main()
{int t;scanf("%d",&t);while(t--){solve();}return 0;
}
更多推荐
cf题目: Monsters And Spells
发布评论