【推导】【找规律】【二分】hdu6154 CaoHaha's staff
题意:网格图。给你一个格点多边形的面积,问你最少用多少条边(可以是单位线段或单位对角线),围出这么大的图形。
如果我们得到了用n条边围出的图形的最大面积f(n),那么二分一下就是答案。
n为偶数时,显然要尽量用斜边去拼矩形,于是f(i)=i*i/4-1 (i mod 4 == 2),f(i)=i*i/4-1(i mod 4 == 0)。
当n为奇数时,尽量用i-1情况下的最长边向外扩张一个单位,于是f(i)=f(i-1)+[(i+1)/4]*2-1(i mod 2 == 1),方括号表示下取整。
n过小时要特判一下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | #include<cstdio> using namespace std; typedef long long ll; ll calc(ll i){ if (i==1ll){ return 0; } if (i==3ll){ return 1ll; } if (i==5ll){ return 5ll; } if (i%4ll==1ll){ ll X=(i-1ll)*(i-1ll)/4ll; return X+(i+1ll)/4ll*2ll-1ll; } else if (i%4ll==2ll){ return i*i/4ll-1ll; } else if (i%4ll==3ll){ ll X=(i-1ll)*(i-1ll)/4ll-1ll; return X+(i+1ll)/4ll*2ll-1ll; } else if (i%4ll==0ll){ return i*i/4ll; } } int T; int main(){ //freopen("g.in","r",stdin); scanf ( "%d" ,&T); ll x; for (;T;--T){ scanf ( "%lld" ,&x); x*=2ll; ll l=1,r=2000000000ll; while (l<r){ ll mid=(l+r)/2ll; if (calc(mid)>=x){ r=mid; } else { l=mid+1; } } printf ( "%lld\n" ,l); } return 0; } |
——The Solution By AutSky_JadeK From UESTC
转载请注明出处:http://www.cnblogs.com/autsky-jadek/
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步