這道題說了一長串背景,剛開始硬是沒看懂。其實題意也是很簡單的,就是在一個網格座標系中,假設一小格的尺寸爲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;
}