3904 - Tile Code
Asia - Seoul - 2007/2008
PDF Submit Ranking
The city of Songpa is now carrying out a project to build a bicycle transportation system called 鈥榞reen Songpa.鈥?By the end of this year, citizens and visitors alike will be able to pick up and drop off bicycles throughout the city. Recently, it was decided to attach a number tag to each bicycle for management use. The bicycles will be under control of the city鈥檚 traffic system.
The number tag contains a tile code of length n , which consists of 1×2 , 2×1 , and 2×2 tiles placed on a 2×n rectangular plate in a way that every cell of the plate is covered by exactly one tile. The plate is divided into 2n cells of size 1×1 . Of course, no two tiles are allowed to overlap each other. The 2×5 plate and a tile code of length 5 are shown in Figures 1 and 2, respectively. The code will always be read from left to right. However, there is no distinction between the top side and the bottom side of the code. The code may be turned upside down. The code shown in Figure 3 is essentially the same code as in Figure 2.
Given a positive integer n , the project director Dr. Yang wants to know how many tile codes of length n there are, that is, the number of ways to place the three kinds of tiles into a 2×n rectangular plate subject to the above conditions. Write a program that can help him.
Input
Your program is to read from standard input. The input consists of T test cases. The number of test cases T is given in the first line of the input. Each test case is given in a single line, which contains a positive integer n , 3n30 .
Output
Your program is to write to standard output. Print exactly one line for each test case. The line should contain the number of tile codes of length n .
Sample Input
2
3
4
Sample Output
3
8
cnt[i]保存的是不忽略左右顺序的,但是左右不能重复;ans保存的是忽略左右顺序的,
当i是奇数的时候,中间是一条2*1的板,左右重复的情况一共是cnt[i/2],cnt[i]+cnt[i/2]表示不忽略左右顺序从左到右和从右到左两种情况之和,故ans[i]= (cnt[i]+cnt[i/2])/2;
当i是偶数的时候,有三种情况:中间是2*2,中间是两个1*2,和中间是一条缝,此时左右重复的分别是cnt[i/2-1],cnt[i/2-1],cnt[i/2],cnt[i]+cnt[i/2]+cnt[i/2-1]+cnt[i/2-1]表示不忽略左右顺序从左到右和从右到左两种情况之和,故ans[i]=(cnt[i]+cnt[i/2]+cnt[i/2-1]*2)/2;
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int cnt[40]={0,1,3};
for(int i=3;i<=30;i++) cnt[i]=cnt[i-1]+2*cnt[i-2];
int ans[40]={0,1,3};
for(int i=3;i<=30;i++)
{
if(i&1) ans[i]=(cnt[i]+cnt[i/2])/2;
else ans[i]=(cnt[i]+cnt[i/2]+cnt[i/2-1]*2)/2;
}
int ci;scanf("%d",&ci);
while(ci--)
{
int n;
scanf("%d",&n);
printf("%d/n",ans[n]);
}
return 0;
}