CF985D Solution
题解
\(O(\sqrt n)\)竟然能过!暴力的胜利
利用贪心思想,我们希望最大的城堡最高,这样总塔数最小。但是高堡需要比它低的城堡做铺垫,因此总趋势应该是先单调不降后单调不升(至少我们可以将之摆放成这样)。也就是设最高值为\(sum\),一排城堡应如此:\(\{n,n+1,...,sum(,sum),sum-1,...,1,0,0,...\}\)。也许会有剩余的沙袋,将其放在与它们等高的沙堡旁即可。暴力枚举\(sum\)与上升的个数即可,根据等差数列求和公式,时间复杂度为\(O(\sqrt n)\)。这是1e9啊喂!咳咳,如果想使时间更加稳定,可以将枚举的部分换为二分,时间为\(O(log_\sqrt n)\)。
AC代码(暴力)
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
int n,h,cnt=0,sum;
scanf("%lld%lld",&n,&h);
for(sum=1;sum<h && cnt+sum<=n;sum++) cnt+=sum;
n-=cnt; int ans=--sum;
for(int i=h;n>=0;i++)
{
if(n>=2*i) n-=2*i,ans+=2;//...,i(,i+1,...,i+1),i,... 对称小伙伴
else if(n>=i) {n-=i,ans++; break;}//...,i-1,i,i-1,... 孤独塔尖人
else break;
}
if(n) ans++;//剩余的
printf("%lld",ans);
return 0;
}