HDU1715 大菲波数 大数相加

本文深入探讨了大数相加的算法实现,使用字符数组或字符串存储大数,通过模拟加法过程解决进位问题。文章提供了两种不同的实现方式,一种是利用C++的string类型,另一种是采用char数组,展示了如何处理不同长度数字的加法。

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

原题链接

大数相加这种题一般是用字符数组或者 string 将其存储或读入,然后从个位开始一步一步模拟加法。容易遇到的坑就是两个数字之和的最高位进位问题,可以在进行加法之前先得到两个数字的位数,比较之后将小的那一个往大的那一个上加,相当于操作的是位数较大(也就是比较长)的那一个数字。例如是s1存了一个3000位的数字,s2存了2000位的数字,只需要将s1与s2之和通过不停的计算存储在s1对应的每一位中即可。

代码如下

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

string add(string s1, string s2) {
    if(s1.length() < s2.length()) {
        string temp = s1;
        s1 = s2;
        s2 = temp;
    }
    for(int i = s1.length()-1, j = s2.length()-1; i>=0; i--, j--) {
        s1[i] = char(s1[i] + (j >= 0 ? s2[j] - '0' : 0));
        if(s1[i] - '0' >= 10) {
            s1[i] = char((s1[i] - '0') % 10 + '0');
            if(i)
                s1[i - 1]++;
            else
                s1 = '1' + s1;
        }
    }
    return s1;
}

string str[1005];

int main() {
    int i, n;
    str[1] = "1";
    str[2] = "1";
    for(i = 3; i < 1005; i++) {
        str[i] = add(str[i - 2], str[i - 1]);
        //printf("%s\n",str[i]);
    }
    cin >> n;
    while(n--) {
        int a;
        cin >> a;
        cout << str[a] << endl;
    }

    return 0;
}

 

这让我想到了刚开始刷 HDU 的时候做过的经典大数相加 HDU-1002 A+BⅡ。当时拿 char 数组顺序把两个数存了进去,然后逆序把个位放到最前面开始一位一位做加法,最后逆序输出,当时 ac 了感觉好厉害哈哈。附上当时 1002 的代码:

#include <stdio.h>
#include <string.h>

int main()
{
    char a[1000], b[1000], c;
    int m[1000], n[1000], t, cnt=1;
    scanf("%d", &t);
    getchar();
    int k = t;
    while(t--){
        memset(m, 0, sizeof(m));
        memset(n, 0, sizeof(n));
        int i;
        for(i=0; (c=getchar())!=' '; i++)
                a[i] = c;
        a[i] = '\0';
        for(i=0; (c=getchar())!='\n'; i++)
                b[i] = c;
        b[i] = '\0';
        int a_len = strlen(a), b_len = strlen(b), max_len;
        for(int i=0; a_len-i-1>=0; i++)
            m[i] = a[a_len-i-1] - '0';
        for(int i=0; b_len-i-1>=0; i++)
            n[i] = b[b_len-i-1] - '0';
        if(a_len < b_len)
            for(int i=a_len; i<b_len; i++)
                m[i] = 0;
        else if(a_len > b_len)
            for(int i=b_len; i<a_len; i++)
                n[i] = 0;
        else{
            m[a_len] = 0;
            n[b_len] = 0;
        }
        max_len = (a_len>=b_len) ? a_len:b_len;
        for(int i=0; i<max_len; i++){
            m[i] += n[i];
            if(m[i] >= 10){
                m[i] -= 10;
                m[i+1] += 1;
            }
        }
        if(m[max_len]==0){
            printf("Case %d:\n", cnt);
            for(int i=0; i<a_len; i++)
                printf("%c", a[i]);
            printf(" + ");
            for(int i=0; i<b_len; i++)
                printf("%c", b[i]);
            printf(" = ");
            for(int i=max_len-1; i>=0; i--)
                printf("%d", m[i]);
        }
        else{
            printf("Case %d:\n", cnt);
            for(int i=0; i<a_len; i++)
                printf("%c", a[i]);
            printf(" + ");
            for(int i=0; i<b_len; i++)
                printf("%c", b[i]);
            printf(" = ");
            for(int i=max_len; i>=0; i--)
                printf("%d", m[i]);
        }
        if(cnt<k)
            printf("\n\n");
        else
            printf("\n");
        cnt++;
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值