Link

分析

就是一道二分答案的题,枚举 \(Frodo\) 能拥有的枕头数,在确定该数后,运用贪心思想,其他人分得的枕头数,应该以他为中心,向四周递减,才能尽可能地少用枕头来满足这个要求,根据两个要点来计算,相邻之差不能大于等于二,因此向左和向右皆为一个公差为1的等差数列,第二个要点就是每人至少要有一个枕头,特判左右数列长度和首项关系即可。

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,k,ans;
inline void read(int &res){
	res=0;
	char c=getchar();
	while(c<'0'||c>'9')c=getchar();
	while(c>='0'&&c<='9')res=(res<<1)+(res<<3)+c-48,c=getchar();
}
bool check(int x){
	int sum=x,len;//提前加入Frodo自身的枕头数,避免重复 
	len=k-1;//数列长度 
	if(len<x)sum+=(x-len+x-1)*(len)/2;
	else sum+=x*(x-1)/2+len-x+1;//首项加末项除以二 
	len=n-k;
	if(len<x)sum+=(x-len+x-1)*(len)/2;
	else sum+=x*(x-1)/2+len-x+1;
	return sum<=m;//最少需要的枕头数是否能够得到 
}
signed main()
{
	read(n);read(m);read(k);
	int l=1,r=m;
	while(l<=r){//二分 
		int mid=(l+r)>>1;
		if(check(mid))ans=mid,l=mid+1;
		else r=mid-1;
	}
	cout<<ans<<endl;
	return 0;
}
posted on 2021-06-25 21:12  漠寒·  阅读(139)  评论(0)    收藏  举报