G - Tiling
题目描述:
Input:
Input is a sequence of lines, each line containing an integer number 0 <= n <= 250.
Output:
For each line of input, output one integer number in a separate line giving the number of possible tilings of a 2xn rectangle.
Sample Input:
Sample Output:
题目大意:
题目给出一个数字n,要平铺2n的矩形,这里的n可以理解为长,然而你只有21与2*2去铺。
思路分析:
这里考到了基础的递归,例如:2n的矩形就有2(n-1)与2*(n-2)来组成,如果不明白就代入一个3就可以清楚知道,23是可以由21或22的矩形来组成,22只有一种组法,用22与21,而21有3种组法,分别是2个21与一个22,或者全部21,还有一种是平铺就是将21以1为宽,以2为长放进去,因为21有3种,有一种与22冲突,所以只有2种即可,那么可以得到通项f(n)=f(n-1)+2f(n-2),难度是要怎么存放大数,这道题可以直接用数组来存所得数就行了,也可以用其他的方法,方法很多种,对了这里有一个很坑爹的,f(0)是存在的并且是1,如果不包括的话,会导致WA。
代码:
#include<stdio.h>
struct lemon
{
int a[10000];
}s[270];
int d=1;
void lemon();
void lemon2();
void lemon3(int e);
void lemon()//这里有一个易错点,因为很多人误认为f(0)不存在,但是题目是存在并且1.
{ //如果不明白可以举例用f(2)=f(0)+2*f(1)来理解就行
s[0].a[0]=1;
s[1].a[0]=1;
}
void lemon2()
{
int b,c,sum;
for(b=2;b<260;b++)//已经枚举了0与1的情况所以直接从2开始,题目只要求在260以内
{
int e=0;//代表进位数
for(c=0;c<d;c++)//用数组存每一个递归得到的方法
{
s[b].a[c]=s[b-1].a[c]+2*s[b-2].a[c]+e;//这里也可以直接用函数来代替
e=s[b].a[c]/10;
s[b].a[c]%=10;
}
while(e)//如果有进位就改变
{
s[b].a[d++]=e%10;
e/=10;
}
}
}
void lemon3(int e)//输出数组中的元素
{
int i;
for(i=d-1;s[e].a[i]==0;i--);//这里有个小技巧,可以直接当s[e][i]!=0时候
for(;i>=0;i--) // 说明这里已经得到方法数了,结束该循环。
{
printf("%d",s[e].a[i]);
}
printf("\n");
}
int main()
{
int a,b,c;
lemon();
lemon2();
while(scanf("%d",&c)!=EOF)
lemon3(c);
}