基于动态规划的高精度加法问题

在没有使用高精度加法算法之前,只能AC20%的数据,在使用高精度加法之后,由于一个数组长度的问题,导致一直只能AC35%的数据,只差“+2”!只差“+2”!只差“+2”!,,,然后就全部AC了!!

高精度加法处理了在运算过程中超出数据表示范围的过大的数的运算问题,以数组的形式存放每一位数字。按照竖式运算方式进行运算。

题目如下:

问题描述

  小牛牛对多米诺骨牌有很大兴趣,然而她的骨牌比较特别,只有黑色和白色的两种。她觉得如果存在连续三个骨牌是同一种颜色,那么这个骨牌排列便是不美观的。现在她有n个骨牌要来排列,她想知道不美观的排列的个数。由于数字较大,数学不好的她不会统计,所以请你来帮忙。希望你帮她求出不美观的排列的个数。

输入数据

  只有一个正整数,即要排列的骨牌个数。

输出数据

  一个数,即不美观的排列个数。

样例输入

4

样例输出

6

样例解释

  有 6 种不美观的排列。

  黑黑黑黑,白白白白,黑黑黑白,白白白黑,黑白白白,白黑黑黑

数据范围

  20%的数据,n<=60;

  50%的数据,n<=6000;

  100%的数据,n<=10000。

  时间限制: 1 sec

  空间限制: 256 MB

提示

  动态规划、高精度加法。

 

代码如下:

#include <iostream>
#include <string.h>
#include <malloc.h>
using namespace std;

char* add(char a[],char b[]){
    int z,pre=0;
    char x,y;
    char* c,*rev;
    int length1= strlen(a);
    int length2=strlen(b);
    int length=length1>length2?length1+2:length2+2;
    int index1=length1-1;
    int index2=length2-1;
    c=(char*)malloc((length+1)*sizeof(char));
    rev=(char*)malloc((length+1)*sizeof(char));
    int index=0;
    while(index1>=0||index2>=0){
        if(index1<0) x='0'; else x=a[index1];
        if(index2<0) y='0'; else y=b[index2];
        z=(int)((x-'0')+(y-'0')+pre);
        pre=0;
        if(z>=10){
            pre=z/10;
        }
        c[index++]=z%10+'0';
        index1--;
        index2--;
    }
    if(pre>0){
        c[index++]=pre+'0';
    }
    c[index]='\0';

    int i=0;
    for(index-=1;index>=0;index--){
        rev[i]=c[index];
        i++;
    }
    rev[i]='\0';
    return rev;
}
char* sub(char a[],char b[]){
    int length,length1,length2,z;
    char x,y;
    char* c,* rev;
    length1=strlen(a);
    length2=strlen(b);
    length=length1>length2?length1:length2;
    c=(char*)malloc((length)*sizeof(char));
    rev=(char*)malloc((length)*sizeof(char));
    int index1=length1-1;
    int index2=length2-1;
    int index=0;
    int pre=0;
    while(index1>=0||index2>=0){
        if(index1<0) x='0'; else x=a[index1];
        if(index2<0) y='0'; else y=b[index2];
        z=(int)((x-'0')-(y-'0')-pre);
        pre=0;
        if(z<0){
            pre=1;
            c[index++]=(z+10)+'0';
        }
        else{
            c[index++]=z+'0';
        }
        index1--;
        index2--;
    }
    c[index]='\0';
    int i=0;
    index--;
    while(c[index]=='0'){
        index--;
    }
    for(;index>=0;index--){
        rev[i++]=c[index];
    }
    rev[i]='\0';
    return rev;
}
char* zhishu(int n){
    char* temp="2";
    for(int i=2;i<=n;i++){
        temp=add(temp,temp);
    }
    return temp;
}
char* fib(int n){
    char* temp1="2";
    char* temp2="4";
    char* temp=NULL;
    for(int i=3;i<=n;i++){
        temp=add(temp1,temp2);
        temp1=temp2;
        temp2=temp;
    }
    return temp;
}
int main()
{
    int number;
    cin>>number;
    if(number<3){
        cout<<0;
        return 0;
    }
    char* fibans=fib(number);
    char* zhishuans=zhishu(number);
    char* ans=sub(zhishuans,fibans);
    for(int i=0;i<strlen(ans);i++){
        cout<<ans[i];
    }

    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值