【推导】【找规律】【二分】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;
}
posted @   AutSky_JadeK  阅读(225)  评论(0编辑  收藏  举报
TVアニメ「Charlotte(シャーロット)」公式サイト TVアニメ「Charlotte(シャーロット)」公式サイト
点击右上角即可分享
微信分享提示