HDU-6154 CaoHaha's staff (找规律+二分)

这道题说了一长串背景,刚开始硬是没看懂。其实题意也是很简单的,就是在一个网格坐标系中,假设一小格的尺寸为1,然后给你个尺寸为N的图形,让你画个封闭的线条把这个图形包起来,在网格中,你只能画小方格的边或者对角线,并且每画一笔就要花费1分钟的时间。最后输出最小时间。

注意,所给的图形的形状可以自由变化。

我们先来找找规律。

首先尺寸为1,你可以这样围:,也可以这样:(这时我们选取第二种围法,即优先画出可围尺寸最大的线条,然后看看能不能把图形装进去)

尺寸为2(4min):尺寸为3(6min):尺寸为4(6min):

尺寸为5(7min):尺寸为6(8min):

其实这个线条的变化应该是这样的:

其中数字表示所需要的笔画次数。

所以不难发现笔画次数的变化从6开始每次都加1。那么线条所围图形的最大尺寸又是如何变化的呢?

从笔画为6开始,每次笔画加1,所围成的图形就会多一个梯形或者矩形,不难发现当笔画数为奇数时就是梯形,偶数就是矩形。

所以最大尺寸=上一个尺寸+梯形或矩形尺寸。而梯形和矩形的尺寸变化我们也可以发现,它是每出现两次后其底边长会加1。

若笔画数为t,那么(t>=6)为什么梯形和矩形的下标为t/4呢,首先是上个梯形与下个梯形之间间隔2个单位,其次每过2个梯形后其大小才会增长。


之后我采用打表的方法,所以这个式子没有继续往下推。

我的代码如下:

#include <cstdio>

using namespace std;

typedef unsigned long long ULL;
const int MAX=1e5+1;
int V[MAX];
int V_MAX;

void init_V()
{
    ULL v=4;
    for(int i=7;i<MAX;i++)
    {
        if(i&1)
            v+=(i-3)/4;
        else
            v+=i/4*2-(i-4)/4;
        V[i]=v;
        if(v>1e9)
        {
            V_MAX=i;
            break;
        }
    }
}

int bf(int n)
{
    int low=7,high=V_MAX,mid;
    while(low<=high)
    {
        mid=(low+high)/2;
        if(n<V[mid])
            high=mid-1;
        else
            low=mid+1;
    }
    if(n<=V[mid-1])
        return mid-1;
    if(n<=V[mid])
        return mid;
    else
        return mid+1;
}

int main()
{
    int t;
    scanf("%d",&t);
    init_V();
    while(t--)
    {
        ULL n;
        scanf("%I64u",&n);
        if(n<=2)
            printf("4\n");
        else if(n<=4)
            printf("6\n");
        else
            printf("%d\n",bf(n));
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值