Greater New York Regional Contest 2017 D.Pavers

Pavers

時間限制: 1 Sec  內存限制: 128 MB

題目描述

In the land of Quendor, walkways, sidewalks and hallways are always 2 mb (mini-bloit, roughly  1/2000  of a bloit) in width.  J. Pierpont Flathead (pictured below) has hired the Frobozz Magic Paver Company to install new walkways in and around all his banks using pavers.  Given the huge number of walkways found at each bank, and the eccentricity of Flathead, Frobozz decided to write a program to determine how many different ways there are to completely cover a walkway using pavers that are 1mb-by-1mb squares, 2mb-by-1mb rectangles in either orientation and right (or L-shaped) tromino pavers in any of the four possible orientations shown below.  This list would then be presented to Flathead so he could choose the patterns he wanted. 
You will help write this program for Frobozz.  Your program must find the total number of tilings and the total number of each paver type used in those tilings.  For instance, there are two tilings of a 2-by-1 walkway using a total of two 1-by-1 square pavers and one 2-by-1 rectangular paver. 
For a 2-by-2 rectangle, there are 11 tilings using a total of 16 1-by-1 square pavers, 8 2-by-1 rectangular pavers and 4 tromino pavers. 
Write a program which takes as input the length n (in mb) of a 2-by-n walkway and outputs the number of tilings by combinations of the three paver types as well as the total number of each type of paver used. 

輸入

The first line of input contains a single decimal integer P, (1≤P≤10000), which is the number of data sets that follow.  Each data set should be processed identically and independently. 
Each data set consists of a single line of input.  It contains the data set number, K, followed by a single space, followed by the decimal length n of the walkway.  Values of n will be chosen so that all of the output values will fit in a 32 bit unsigned integer. 

輸出

For each data set there is one line of output.  The output line consists of the five decimal integers separated by a single space:  the data set number, K followed by the total number of tilings of a 2-by-n walkway, the total number of 1-by-1 square pavers used, the total number of 1-by-2 rectangular pavers used and the total number of tromino pavers used for these tilings. 

樣例輸入

2
1 1
2 2

樣例輸出

1 2 2 1 0
2 11 16 8 4

題目大意:給你個2*n的格子,給你三種地板,旋轉後得到如下圖所示的幾種地板,讓你鋪滿整個格子,問對每個給定的n有多少種鋪法,這些方法一共會用掉三種地板各多少塊。(保證輸出都在無符號整形之內)

思路:n==1和n==2時的結果手痠就可以,從n==3開始我們就可以找到規律:

    1、首先是最明顯的,n可以從n-1轉化而來,轉化的方案無非只有兩種:

    2、其次我們發現,n也可以從n-2轉化而來,轉化的方案有七種(去掉會和從n-1轉化而來重複的)(畫圈的爲未重複的):

    3、n同樣可以從n-i轉化而來(2<=i<=n),這時我們分類討論:

           ①i%2==1的情況:不會畫圖,畫圖醜見諒......這裏以i==3爲例。當i>3時情況類似,只是在中間加了兩個1*2的地板(對左邊六個來說,加的兩個1*2地板分插在了L型板邊上,上下兩層各一個;對右邊兩個來說,加的地板在本來的1*2的地板與1*1的地板之間)。

           ②i%2==0的情況:這裏是以i==4爲例的,當i>4時情況也類似,也是在中間加兩塊1*2的地板,加地板的方法與i%2==1時的情況類似,就不再贅述了。

然後利用這幾條規律寫出方法數以及三種地板用量的遞推關係,暴力打表後發現n最多到15,n==16時所用的1*1的地板數就爆了unsigned int了,所以打表到15這道題就沒問題了......

最後附上代碼:

#include <bits/stdc++.h>
struct node
{
    long long f,a,b,c; //f爲方法數,a爲1*1的地板數,b爲1*2的地板數,c爲L形的地板數
};
node z[16];
int main()
{
    int p,k,n,i,j;
    scanf("%d",&p);
    z[1].f=z[1].a=2;
    z[1].b=1;
    z[1].c=0;
    z[2].f=11;
    z[2].a=16;
    z[2].b=8;
    z[2].c=4;
    z[0].f=1;   //以上均爲初始化,其實是懶得考慮越界情況了....
    for (i=3;i<=15;i++)   //f,a,c均用我們得到的遞推關係寫出
    {
        z[i].f=z[i-2].f*7+z[i-1].f*2;
        for (j=3;j<=i;j++)
            z[i].f+=8*z[i-j].f;
        z[i].a=z[i-1].a*2+z[i-2].a*7+z[i-1].f*2+z[i-2].f*8;
        for (j=3;j<=i;j++)
            z[i].a+=8*(z[i-j].f+z[i-j].a);
        z[i].c=z[i-1].c*2+z[i-2].c*7+z[i-2].f*4;
        for (j=3;j<=i;j++)
            z[i].c+=8*(z[i-j].f+z[i-j].c);
        z[i].b=(z[i].f*2*i-z[i].a-z[i].c*3)/2;    //1*2的地板數懶得算了...直接用面積減去其他兩種地板所佔的面積來求
    }
    while (p--)
    {
        scanf("%d%d",&k,&n);
        printf("%d %lld %lld %lld %lld\n",k,z[n].f,z[n].a,z[n].b,z[n].c);
    }
    return 0;
}

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