【3003】&&【9105】高精度求积 【高精度压位】

高精度求积

Time Limit: 10 second
Memory Limit: 2 MB

问题描述
输入两个高精度正整数m和n(m和n均小于100位),求这两个高精度的积

Input

文件输入两行,第一行输入m的值,第二行输入n的值

Output

输出积,最后不带任何符号(不用换行)

Sample Input

36
3

Sample Output

108

【题解】

代码提供的是4位的压位。5位压位会导致一个点通过不了。应该是做乘法的时候溢出了。用了unsigned long long 。。。

【代码】

提供一张图片供理解。

#include <cstdio>
#include <string>
#include <iostream>

using namespace std;

const int MAXN = 800;

string s1,s2;
int l1,l2,l3;
unsigned long long  ta[MAXN],tb[MAXN],a[MAXN],b[MAXN],c[MAXN];

void input_data()
{
    cin >> s1;
    cin >> s2;
    l1 = s1.size();
    l2 = s2.size();
    for (int i = 1;i <= l1;i++) //ta和tb用于以不压位的形式存储输入的数据
        ta[i] = s1[l1-i] - '0';
    for (int i = 1;i <= l2;i++)
        tb[i] = s2[l2-i] - '0';
    for (int i = 1;i <= l1 / 4;i++) //4个数字4个数字地存入相应的a和b数组.
        a[i] = ta[4*i]*1000 + ta[4*i-1]*100 + ta[4*i-2]*10 + ta[4*i-3];
    int a1 = l1 / 4;
    int d = l1 % 4; //有时候不会刚好数的长度为4的倍数,会有剩下的。直接放到最后面。
    if (d != 0)
        {
            int now = 0;
            for (int i= 1; i <= d;i++) //获取剩余的数字
                    now = now*10 + ta[l1-i+1];
            a1++;
            a[a1] = now;//存入a数组中
        }
    for (int i = 1;i <= l2 / 4;i++) //b数组也是同样的步骤
        b[i] = tb[4*i]*1000 + tb[4*i-1]*100 + tb[4*i-2]*10 + tb[4*i-3];
    int b1 = l2 / 4;
    int re = l2 % 4;
    if (re != 0)
        {
                int dd = 0;
                for (int i = 1;i <= re;i++)
                    dd = dd*10 + tb[l2-i+1];
                b1++;
                b[b1] = dd;
        }
    l3 = l1 + l2 ;
}

void get_ans()
{
    for (int i = 1 ;i <= MAXN - 20;i++)
        c[i] = 0;
    for (int i = 1;i <= l1;i++)
        for (int j = 1;j <= l2;j++)
            c[i+j-1] = c[i+j-1] + a[i]*b[j]; //c[i+j-1]+=a[i]*b[j] 这是高精度乘法的通用步骤
    for (int i = 1;i <= l3;i++) //接下来开始进位,和普通的高精度乘法有所不同。
        if (c[i] >= 10000)
            {
                c[i+1] = c[i+1] + (c[i] / 10000);
                c[i] = c[i] % 10000;
            }
    while (c[l3+1] >0)
        {
            l3++;
            c[l3+1] = c[l3+1] + (c[l3] / 10000);
            c[l3] = c[l3] / 10000;
        }
    while (c[l3]==0 && l3>0) l3--; //防止位数超过了实际位数。做一下检验工作。
}

void output_ans()
{
    printf("%d",c[l3]); //最高位前面是不会有多余的0的,所以直接输出。如a[1]=462 a[2]=56  l3=2 a[l3] = 56 这个时候你不能在56前面加0.而465前要加0
    //最后结果就是560462
    for (int i = l3-1;i >= 1;i--) //控制一下输出就可以了。
        {
            if (c[i] >= 1000)
                {
                    printf("%d",c[i]);
                    continue;
                }
            if (c[i] >= 100)
                {
                    printf("0%d",c[i]);
                    continue;
                }
            if (c[i] >= 10)
                {
                    printf("00%d",c[i]);
                    continue;
                }
            if (c[i] >=1)
                {
                    printf("000%d",c[i]);
                }
            printf("0000");
        }
}

int main()
{
    input_data();
    get_ans();
    output_ans();
    return 0;
}


 

原文地址:https://www.cnblogs.com/AWCXV/p/7632487.html