2.2基本算法之递归和自调用函数_9273: Pku2506Tiling 2.2基本算法之递归和自调用函数...

8778b17f58731465efe246abe9f65c53.png

【9273:PKU2506Tiling】BY Oler025
一、【题目】
总时间限制:
2000ms
单个测试点时间限制:
1000ms
内存限制:
131072kB
描述
对于一个2行N列的走道。现在用1*2,2*2的砖去铺满。问有多少种不同的方式。
下图是一个2行17列的走道的某种铺法。
输入
整个测试有多组数据,请做到文件底结束。每行给出一个数字N,0 <= n <= 250
输出
如题
【样例输入】
2
8
12
100
200
【样例输出】
3
171
2731
845100400152152934331135470251
1071292029505993517027974728227441735014801995855195223534251
二、数据结构:
利用了二维数组,递归函数,和函数的自调用。
三、题目分析:
找出递推关系式即可:
最后一块1*2横放: f(n)=f(n-2)
最后一块1*2竖放: f(n)=f(n-1)
最后一块2*2 : f(n)=f(n-2)
故f(n)=f(n-1)+2*f(n-2);
边界条件 f(0)=1;f(1)=1;f(2)=3
dp[0][0]=1,dp[0][1]=1;
dp[1][0]=1,dp[1][1]=1;
四、算法说明:
用每一列数组的第一位去保存数组的长度,后面的位数就是数字,数字由个位开始,依次向后,倒序排列,方便进行计算的进位。
由于不只一组数据,所以要用While{scanf(“%d”,&n)}。
又由于最后结果会很大,所以要使用高精度保存。
数据长度很长,所以要把每一位数存在二维数组中,在需要时取出,利用二维素组进行计算,难点就是设计高精度算法。
在数组中存数字的时候利用for循环,不断地%10,在保存除后数字,直到计算到最后一位,即可实现对长数的保存。
进行加法运算时调用函数,从个位开始相加,递归调用,再处理好进位即可。
五、代码:
#include <iostream>
using namespace std;
int dp[300][300];//用个2维数组把每一个数的每一位都存下来
void printf(int dp[])//打印结果
{
for(int i=dp[0];i>=1;i--)
{
cout<<dp[i];
}
printf("n");
}
int* cheng(int a[],int b)//高精度乘单精度
{
for(int i=1;i<=a[0];i++)
{
a[i]*=b;
}
for(int j=1;j<=a[0];j++) //处理进位
{
if(a[j]>=10)
{
a[j]%=10;
a[j+1]++;
}
}
while(a[a[0]+1]>0) a[0]++; //更正位数
return a;
}
int* jia(int a[],int b[]) //高精度加法
{
if(a[0]<b[0]) a[0]=b[0];
for(int i=1;i<=a[0];i++)
{
a[i]+=b[i];
}
for(int j=1;j<=a[0];j++)//处理进位
{
if(a[j]>=10)
{
a[j]%=10;
a[j+1]++;
}
}
while(a[a[0]+1]>0) a[0]++; //更正位数
return a;
}
void give(int ans[],int dp[])//赋值,把ans数组的值全部给dp数组
{
for(int i=0;i<=ans[0];i++)
{
dp[i]=ans[i];
}
}
int * f(int n)
{
if(dp[n][0]!=0) return dp[n];
else if(0==n) return dp[0];
else if(1==n) return dp[1];
else
{
int t1[300]={0};
int t2[300]={0};
give(f(n-1),t1);
give(f(n-2),t2);
give(jia(t1,cheng(t2,2)),dp[n]);
return dp[n];
}
}
int main()
{
dp[0][0]=1,dp[0][1]=1;//前面是位数,后面是数
dp[1][0]=1,dp[1][1]=1;
int n;
while(scanf("%d",&n))
{
f(n);
printf(dp[n]);
}
return 0;
}
六、算法分析:
在算法中经过测试发现,在输出长数据时,cout要比printf更加好用,printf会导致超时,改了好久才发现是printf的问题。
利用while反复循环scanf,再调用函数,以达到去对多组数据进行检测的目的。
函数的递归容易实现,难点就是高精度加法计算的设计,乘法的计算由于题意可知,可以看成是数组对自身的加法,容易计算。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值