题意:给出若干个1组成的数,可将相连的1写成2,问有多少种写法
思路:将由n个1组成的大数看成一个n阶的超级楼梯,1代表向上一阶,2代表向上2阶。此题则转换为到n阶楼梯的解法。
根据问题的实际意义或者数学归纳可知为斐波那契数列问题。
由于题目所给数据为大数的集合,因此用二维数组保存。
应用整形数组比字符型简单,因为结果无论如何都要转化为整形,因此用整形数组。
由于用整型数组,则没有办法求大数相加的位数,应当想一个办法解决这个问题:
由于是递推,所以后面大数的位数与前面的位数的最大值相差0或1位,可通过最高位是否进位来确定相差位数。
再者:大数的相加,相加大数参与运算要转化为低到高存储,因此越少转换越好。
失误:不知道文中l的问题怎么解决;
思路局限于以前的题目之中,不能做到创新;
没有想到该怎么将大数数组倒置,忽略了初始条件1位数倒置不倒置都一样;
没有想到直接用整形的数组组,简单又整洁,用字符换开换去麻烦!!!
代码如下:
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
int n ,t,i,l,cnt,j,ls,a[1000][501]={0},b[1001]={0};//数组定义在maihn函数之外可以开的更大,因为main函数有限制
char str[222];
a[1][0]=1; //俗称打表
a[2][0]=2;
l=0; //用来记录大数的位数,如果相加比最长的还长,那么l++
b[1]=0;
b[2]=0;
for(i=3;i<1000;++i) //主干程序
{ //每个操作的树都为大数,并且要操作一个集合的大数,
cnt=0; // 一个大数为一个字符数组,因此用二维数组保存大数集合
for(j=0;j<=l;++j)
{
a[i][j]=a[i-1][j]+a[i-2][j]+cnt; //数组越界 我发现不只我自己出现这个问题,理论还是要去实践的
if(a[i][j]>9)
{
a[i][j]-=10;
cnt=1;
}
else
{
cnt=0;
}
}
if(cnt==1)
{
++l;
a[i][j]=1;
}
b[i]=l;//用一个数组记录下每个大数的位数
}
scanf("%d",&t);
while(t--)
{
getchar();
scanf("%s",str);
ls=strlen(str);
for(i=b[ls];i>=0;--i)
{
printf("%d",a[ls][i]);
}
printf("\n");
}
return 0;
}