ybt1676手机游戏

1676:手机游戏

时间限制: 1000 ms 内存限制: 131072 KB

【题目描述】

明明的手机上有这样一个游戏,一排\(n\)个怪物,每个怪物的血量是\(m_i\)。现在明明可以射出k个伤害均为\(p\)的火球,当某个火球射到第\(i\)个怪物,除了这个怪物会掉血\(p\)以外,它左边的第\(j\)个怪物\((j≤i)\),也会遭到\(max(0,p−(i−j)^2)\)的溅射伤害。当某个怪物的血量为负的时候,它就死了,但它的尸体依然存在,即其他怪物不会因为它死而改变位置。

明明想用这\(k\)个火球消灭掉所有的怪物,但他同时希望每个火球的伤害\(p\)能尽可能的小,这样他才能完美过关。

所有数均为整数。

【输入】

第一行两个数\(n,k\)

第二行\(n\)个数\(m_1,m_2,…,m_n\)

表示每个怪物的生命值。

【输出】

一行一个整数表示最小的符合要求的\(p\)值。

【输入样例】

3 1
1 4 5

【输出样例】

6

【数据规模】

对于30%的数据,\(n≤500\)

对于100%的数据,\(1≤n≤50000,1≤k≤100000,1≤mi≤10^9\)


二分答案。
问题在于题目要仔细读,j 的含意要认真体会!


#include<bits/stdc++.h>
using namespace std;
const int maxn=5e4+10;
int n,sz[maxn],k,m[maxn];
bool pd(long long cur)
{
	int pos=n;
	for(int i=1;i<=k;++i)
	{
		m[pos]-=cur;
		for(int j=1;pos-j>0&&cur-j*j>0;++j)m[pos-j]-=cur-j*j;
		//for(int j=pos;j>0&&(pos-j)*(pos-j)<cur;--j)m[j]-=cur-(pos-j)*(pos-j);
		while(m[pos]<0&&pos>0)pos--;
	}
	return pos==0;
}
int main()
{
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;++i)scanf("%d",&sz[i]);
	long long l=0,r=2e9+1,ans;
	while(l<=r)
	{
		long long cur=(l+r)>>1;
		for(int i=1;i<=n;++i)m[i]=sz[i];
		if(pd(cur))ans=cur,r=cur-1;
		else l=cur+1;
	}
	cout<<ans<<endl;
	return 0;
}

posted on 2024-12-25 09:47  gryzy  阅读(1)  评论(0编辑  收藏  举报

导航