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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章