POJ 2116

本文介绍了一种特殊的二进制运算方法,该方法基于斐波那契数列将二进制数转换为十进制,并实现两数相加。通过去除连续的1确保了数列的标准形式,最终输出标准形式的二进制结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:以二进制的形式给出一串数列(例: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>
using namespace std;
int main()
{
  double f[50]={1,2},sum1,sum2,sum;
  int s1[40],s2[40],s3[40],n;
  string a,b;
  char *a1,*a2,*a3;
  for(int i=2;i<50;i++)
      f[i]=f[i-1]+f[i-2];
  while(cin>>a>>b)
  {
      int t1=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
              <<"  ";
          for(int i=0;i<s3[0]+1;i++)
              cout<<"-";
          cout<<endl<<setw(s3[0]+3)<<a3<<endl<<endl;
      }
      else if(a[t1]!='0'&&b[t2]=='0')
      {
          cout<<setw(s3[0]+3)<<a1<<endl
              <<"+"<<setw(s3[0]+2)<<0<<endl
              <<"  ";
          for(int i=0;i<s3[0]+1;i++)
              cout<<"-";
          cout<<endl<<setw(s3[0]+3)<<a3<<endl<<endl;
      }
      else if(a[t1]=='0'&&b[t2]=='0')
      {
          cout<<setw(3)<<0<<endl
              <<"+"<<setw(2)<<0<<endl
              <<"  -"<<endl<<setw(3)<<0<<endl<<endl;
      }
      else
      {
          cout<<setw(s3[0]+3)<<a1<<endl
              <<"+"<<setw(s3[0]+2)<<a2<<endl
              <<"  ";
          for(int i=0;i<s3[0]+1;i++)
              cout<<"-";
          cout<<endl<<setw(s3[0]+3)<<a3<<endl<<endl;
      }
      delete []a1;
      delete []a2;
      delete []a3;
  }
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值