POJ 2116
来源:互联网 发布:程序员能做到多少岁 编辑:程序博客网 时间:2024/06/05 09:59
题意:以二进制的形式给出一串数列(例:11101),要求按照斐波那契数列的规律化为10进制,斐波那契数列1,2,3,5,8,13,21···,其标号分别为F0,F1,F2,F3···,化为十进制:1*1+2*0+3*1+5*1+8*1=17.数列11101的标准形式为:100101(中间不能有连续两个或两个以上的1出现即为标准形式,对每个十进制数字,标准形式有且只有一种)。
要求输入两串数列,用空格隔开。输出两串数列的标准形式以及两串数列的相加结果,结果也要用标准形式表示。
思路:先将输入的两串数列化为两个十进制数字,再计算其和,得到三个十进制数字,对于每个十进制数字,按照公式:F[N]<=NUM<F[N+1](F[N]表示第N个斐波那契数);NUM-=F[N];进行迭代,直到NUM==0为止。
最后要注意前导零的情况,开始输入是先进行一次扫描清前导零(开始没注意,贡献了一次WA~~(╯﹏╰)~~)
PS:输入的数据可能是0 0,0 XXX,XXX 0.
代码:
#include<iostream>
#include<iomanip>
#include<string>
usingnamespacestd;
intmain()
{
doublef[50]={1,2},sum1,sum2,sum;
int s1[40],s2[40],s3[40],n;
stringa,b;
char*a1,*a2,*a3;
for(int i=2;i<50;i++)
f[i]=f[i-1]+f[i-2];
while(cin>>a>>b)
{
intt1=0,t2=0;
for(int i=0;i<a.size();i++)
if(a[i]!='0'){t1=i;break;}
for(int i=0;i<b.size();i++)
if(b[i]!='0'){t2=i;break;}
sum1=sum2=sum=0;
memset(s1,-1,sizeof(s1));
memset(s2,-1,sizeof(s2));
memset(s3,-1,sizeof(s3));
for(int i=a.size()-1,j=0;i>=0;i--,j++)
if(a[i]=='1')sum1+=f[j];
for(int i=b.size()-1,j=0;i>=0;i--,j++)
if(b[i]=='1')sum2+=f[j];
sum=sum1+sum2;
n=0;
while(sum1>0)
{
int i=0;
while(sum1>=f[i])
i++;
s1[n++]=--i;
sum1-=f[i];
}
n=0;
while(sum2>0)
{
int i=0;
while(sum2>=f[i])
i++;
s2[n++]=--i;
sum2-=f[i];
}
n=0;
while(sum>0)
{
int i=0;
while(sum>=f[i])
i++;
s3[n++]=--i;
sum-=f[i];
}
a1=new char[s1[0]+2];
a2=new char[s2[0]+2];
a3=new char[s3[0]+2];
memset(a1,'0',(s1[0]+2)*sizeof(char));
memset(a2,'0',(s2[0]+2)*sizeof(char));
memset(a3,'0',(s3[0]+2)*sizeof(char));
a1[s1[0]+1]=a2[s2[0]+1]=a3[s3[0]+1]='\0';
for(int i=0;s1[i]!=-1;i++)
a1[s1[0]-s1[i]]='1';
for(int i=0;s2[i]!=-1;i++)
a2[s2[0]-s2[i]]='1';
for(int i=0;s3[i]!=-1;i++)
a3[s3[0]-s3[i]]='1';
if(a[t1]=='0'&&b[t2]!='0')
{
cout<<setw(s3[0]+3)<<0<<endl
<<"+"<<setw(s3[0]+2)<<a2<<endl
<<" " ;
#include<iomanip>
#include<string>
usingnamespacestd;
intmain()
{