【推導】【找規律】【二分】hdu6154 CaoHaha's staff
阿新 • • 發佈:2017-08-20
print turn else 多邊形 pac 線段 取整 log 推導
題意:網格圖。給你一個格點多邊形的面積,問你最少用多少條邊(可以是單位線段或單位對角線),圍出這麽大的圖形。
如果我們得到了用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過小時要特判一下。
#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; }
【推導】【找規律】【二分】hdu6154 CaoHaha's staff