HDU-1002

题目描述:

 

解析:

 大数加法问题:

       最普通的想法就是将大数读取一位一位拆解,然后进行加法,可行!(代码如下 <第一个> )

如何降低时间空间复杂性:

       考虑到一个 unsigned int 型可以存放最大的整数为 \large 2^{^{32}} - 1(根据编译器不同),将大数每 9 位拆解成一个整数,然后在进行加法。(代码如下 <第二个>)

 

代码:

#include<stdio.h>
#include<memory.h>
#define SIZE 1010

int a[SIZE], b[SIZE];
int sum[SIZE];

int count_a, count_b;

void init();
void reverse_array(int * arr, int count_arr);
// 一位一位的进行加法
void add(int * arr_a, int * arr_b, int carr_a, int carr_b);
void print(int i);

int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        init();
        char ch;
        if (!i)
        {
            getchar();
        }
        while((ch = getchar()) != ' ')  // 获取数组 a
        {
            a[count_a] = ch - '0';
            count_a++;
        }
        while((ch = getchar()) != '\n')  // 获取数组 b
        {
            b[count_b] = ch - '0';
            count_b++;
        }

        // 个位对齐
        reverse_array(a, count_a);
        reverse_array(b, count_b);

        add(a, b, count_a, count_b);

        print(i);
    }
    return 0;
}

void init()
{
    count_a = 0;
    count_b = 0;
    memset(a, 0, SIZE * sizeof(int));
    memset(b, 0, SIZE * sizeof(int));
    memset(sum, 0, SIZE * sizeof(int));
    return;
}

void reverse_array(int * arr, int count_arr)
{
    for (int i = 0; i <= (count_arr - 1) / 2; i++)
    {
        int temp = arr[i];
        arr[i] = arr[count_arr - i - 1];
        arr[count_arr - i - 1] = temp;
    }
    return;
}


void add(int * arr_a, int * arr_b, int carr_a, int carr_b)
{
    int length = carr_a > carr_b ? carr_a : carr_b;
    length++;
    int carry = 0;
    for (int i = 0; i < length; i++)
    {
        sum[i] = a[i] + b[i] + carry;
        carry = 0;
        if (sum[i] > 9)
        {
            sum[i] -= 10;
            carry = 1;
        }
    }
    return;
}

void print(int i)
{
    int length = count_a > count_b ? count_a : count_b;
    length++;
    if (i != 0)
    {
        printf("\n");
    }
    printf("Case %d:\n", i + 1);
    for (int j = count_a; j > 0; j--)
    {
        printf("%d", a[j - 1]);
    }
    printf(" + ");
    for (int j = count_b; j > 0; j--)
    {
        printf("%d", b[j - 1]);
    }
    printf(" = ");
    for (int j = length; j > 0; j--)
    {
        if(j == length && sum[j - 1] == 0)
            continue;
        printf("%d", sum[j - 1]);
    }
    printf("\n");
    return;
}
#include <stdio.h>
#include <string.h>
#include <memory.h>
#define SIZE 1010
#define MAX 200

// 优化版大数加法
char ch_a[SIZE], ch_b[SIZE];
int a[MAX], b[MAX];
int sum[MAX];

int count_a, count_b;

void init();
void handle(char * ch, int * arr, int * carr);
void add(int * arr_a, int * arr_b, int carr_a, int carr_b);
void print(int i);

int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        init();
        scanf("%s %s", ch_a, ch_b);

        // 处理字符串
        handle(ch_a, a, &count_a);
        handle(ch_b, b, &count_b);

        add(a, b, count_a, count_b);

        print(i);
    }
    return 0;
}

void init()
{
    count_a = 0;
    count_b = 0;
    memset(ch_a, 0, SIZE * sizeof(char));
    memset(ch_b, 0, SIZE * sizeof(char));
    memset(a, 0, MAX * sizeof(int));
    memset(b, 0, MAX * sizeof(int));
    memset(sum, 0, MAX * sizeof(int));
    return;
}

void handle(char * ch, int * arr, int * carr)
{
    int length = strlen(ch);
    int i;
    for (i = length; i >= 9; i -= 9)
    {
        int temp = 0;
        for (int j = 9; j > 0; j--)
        {
            temp *= 10;
            temp += ch[i - j] - '0';
        }
        arr[*carr] = temp;
        (*carr)++;
    }
    if (i == 0)
        return;
    int temp = 0;
    for (int j = i; j > 0; j--)
    {
        temp *= 10;
        temp += ch[i - j] - '0';
    }
    arr[*carr] = temp;
    (*carr)++;

    return;
}

void add(int * arr_a, int * arr_b, int carr_a, int carr_b)
{
    int length = carr_a > carr_b ? carr_a : carr_b;
    length++;
    int carry = 0;
    for (int i = 0; i < length; i++)
    {
        sum[i] = sum[i] + a[i] + b[i];
        if (sum[i] > 999999999)
        {
            sum[i] -= 1000000000;
            sum[i + 1] += 1;
        }
    }
    return;
}

void print(int i)
{
    int length = count_a > count_b ? count_a : count_b;
    if (i != 0)
        printf("\n");
    printf("Case %d:\n", i + 1);
    printf("%s + %s = ", ch_a, ch_b);
    if (sum[length] != 0)
        printf("%d%09d", sum[length], sum[length - 1]);
    else
        printf("%d", sum[length - 1]);
    for (int j = length - 2; j >= 0; j--)
        printf("%09d", sum[j]);
    printf("\n");
    return;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值