求助大佬,不明白为什么只过了一个点:(

P1303 A*B Problem

Miier @ 2022-07-22 09:57:37

#include <stdio.h>
#include <string.h>
typedef struct
{
    int num[11000];
    int len;
    int neg;
}BIGINT;
BIGINT str2int(char* p);
BIGINT add(BIGINT a,BIGINT b);//高精度加法
BIGINT sub(BIGINT a,BIGINT b);//高精度减法
BIGINT mul(BIGINT a,BIGINT b);//高精度乘低精度
int main()
{
    char sa[11000],sb[11000];
        scanf("%s %s",sa,sb);
        BIGINT ia=str2int(sa),ib=str2int(sb);
        BIGINT ans=mul(ia,ib);
        if(ans.neg) printf("-");
        for(int i=ans.len-1;i>=0;i--)  printf("%d",ans.num[i]);
}
BIGINT str2int(char* p)
{
    BIGINT ans={{0},0,0};
    for(int i=strlen(p)-1;i>=0;i--)
    {
        ans.num[ans.len++]=p[i]-'0';
    }
    return ans;
}
BIGINT add(BIGINT a,BIGINT b)
{
    int len=a.len>b.len?a.len:b.len;
    BIGINT ans={{0},len,0};
    int temp,carry=0;
    for(int i=0;i<len;i++)
    {
        temp=a.num[i]+b.num[i]+carry;
        ans.num[i]=temp%10;
        carry=temp/10;
    }
    if(carry)
    {
        ans.num[len]=carry;
        ans.len=len+1;
    }
    return ans;
}
BIGINT sub(BIGINT a,BIGINT b)
{
    BIGINT ans={{0},a.len>b.len?a.len:b.len,0};
    if(a.len<b.len)//确保大数减去小数
    {
        ans=sub(b,a);
        ans.neg=1;
        return ans;
    }
    else if(a.len==b.len)
    {
        for(int i=a.len-1;i>=0;i--)
        {
            if(a.num[i]<b.num[i])
            {
                ans=sub(b,a);
                ans.neg=1;
                return ans;
            }
        }
    }
    int temp,carry=0;
    for(int i=0;i<a.len;i++)
    {
        temp=a.num[i]-b.num[i]-carry;
        carry=temp<0?1:0;
        ans.num[i]=(temp+10)%10;//借位可能产生负数,加10不影响余数
    }
    // for(int i=a.len-1;i>=0;i--)//确定相减结果的位数
    // {
    //     if(ans.num[i]!=0)
    //     {
    //         ans.len=i+1;
    //         return ans;
    //     }
    // }
    // ans.len=1;
    ans.len=a.len>b.len?a.len:b.len;//确定相减的位数,注意初始化ans.len
    while(ans.num[ans.len-1]==0&&ans.len>1)   ans.len--;
    return ans;
}
BIGINT mul(BIGINT a,BIGINT b)
{
    BIGINT c={{0},a.len+b.len,0};//a*b的最大长度位a、b的幂次和
    int temp=0,carry=0;
    for(int i=0;i<a.len;i++)
    {
        for(int j=0;j<b.len;j++)
        {
            temp=a.num[i]*b.num[j]+carry+c.num[i+j];
            c.num[i+j]=temp%10;
            carry=temp/10;
        }
        c.num[i+b.len]=carry;
    }
    c.len=a.len+b.len;
    while(c.num[c.len-1]==0&&c.len>1)   c.len--;
    return c;

}

by tin_ingot @ 2022-07-22 10:34:33

@Miier 高精乘高精


by Miier @ 2022-07-22 10:43:07

@滑稽人 前面注释写错了,后面是高精度乘高精度的算法。大佬有空的话能帮忙看看吗,感谢:)


by tin_ingot @ 2022-07-22 10:57:14

@Miier 精简了一下

#include<stdio.h>
#include<string.h>
#define N 50010
char x[N],y[N];
int a[N],b[N],c[N];
int main()
{
    scanf("%s%s",x,y);
    a[0]=strlen(x);b[0]=strlen(y);
    for(int i=1;i<=a[0];i++) a[i]=x[a[0]-i]-'0';
    for(int i=1;i<=b[0];i++) b[i]=y[b[0]-i]-'0';
    for(int i=1;i<=a[0];i++)
    for(int j=1;j<=b[0];j++)
    c[i+j-1]+=a[i]*b[j];
    int len=a[0]+b[0];
    for(int i=1;i<=len-1;i++)
    if(c[i]>9)
    {
        c[i+1]+=c[i]/10;
        c[i]%=10;
    }
    while(c[len]==0&&len>1) len--;
    for(int i=len;i>=1;i--) printf("%d",c[i]);
    return 0;
} 

by Miier @ 2022-07-22 11:11:34

@滑稽人 多谢大佬的代码,看了你的代码之后我还是不明白自己的代码错在哪里了:( 大佬可否看看我的代码,多谢


by tin_ingot @ 2022-07-22 11:13:46

@Miier 那我的看懂了吗?


by tin_ingot @ 2022-07-22 11:35:18

@Miier 改好了:

#include <stdio.h>
#include <string.h>
#define N 4000+10
typedef struct
{
    int num[N],len;
} lll;
lll to_int(char *p)
{
    lll ans={{0},0};
    for(int i=strlen(p)-1; i>=0; i--)
    {
        ans.num[ans.len++]=p[i]-'0';
    }
    return ans;
}
void mul(lll a,lll b)
{
    lll c= {{0},N};
    for(int i=0; i<a.len; i++)
    {
        for(int j=0; j<b.len; j++)
        {
            c.num[i+j]+=a.num[i]*b.num[j];
        }
    }
    for(int i=0; i<N; i++)
    {
        c.num[i+1]+=c.num[i]/10;
        c.num[i]%=10;
    }
    c.len=N-1;
    while(c.num[c.len]==0&&c.len>0) c.len--;
    for(int i=c.len;i>=0;i--) putchar(c.num[i]^48);
}
int main()
{
    char sa[11000],sb[11000];
    scanf("%s%s",sa,sb);
    lll ia=to_int(sa);
    lll ib=to_int(sb);
    mul(ia,ib);
}

by Miier @ 2022-07-22 18:17:17

@滑稽人 结合大佬的代码我终于搞明白了!我原来的代码出错的原因是每次进第一层循环carry没有重新设置为0.多谢大佬解答:)


by LeeJC @ 2022-10-28 18:23:38

#include <stdio.h>
#include <string.h>
int main()
{
    char s[2001],ss[2001];
    scanf("%s %s",s,ss);
    int i,j,a[2002],b[2002],c[500001];
    a[0]=strlen(s);
    b[0]=strlen(ss);
    for(i=1;i<=a[0];i++)
        a[i]=s[a[0]-i]-'0';
    for(i=1;i<=b[0];i++)
        b[i]=ss[b[0]-i]-'0';
    for(i=1;i<=a[0];i++)
        for(j=1;j<=b[0];j++)
        c[i+j-1]=a[i]*b[j];
    for(i=1;i<a[0]+b[0];i++)
        if(c[i]>9)
        {
            c[i+1]+=c[i]/10;
            c[i]%=10;
        }
    int len=a[0]+b[0];
    while(c[len]==0&&len>1)
    len--;
    for(i=len;i>0;i--)
    printf("%d",c[i]);
    return 0;
}

@滑稽人 我靠大佬,一模一样啊,就AC了一个点


by tin_ingot @ 2022-10-28 18:38:39

@LeeJC 首先,你的代码要把数组开在外面,不然main函数可能会爆内存:

#include <stdio.h>
#include <string.h>
char s[2001],ss[2001];
int i,j,a[2002],b[2002],c[500001];
int main()
{
    scanf("%s %s",s,ss);
    a[0]=strlen(s);
    b[0]=strlen(ss);
    for(i=1;i<=a[0];i++)
        a[i]=s[a[0]-i]-'0';
    for(i=1;i<=b[0];i++)
        b[i]=ss[b[0]-i]-'0';
    for(i=1;i<=a[0];i++)
        for(j=1;j<=b[0];j++)
        c[i+j-1]=a[i]*b[j];
    for(i=1;i<a[0]+b[0];i++)
        if(c[i]>9)
        {
            c[i+1]+=c[i]/10;
            c[i]%=10;
        }
    int len=a[0]+b[0];
    while(c[len]==0&&len>1)
    len--;
    for(i=len;i>0;i--)
    printf("%d",c[i]);
    return 0;
}

by tin_ingot @ 2022-10-28 18:55:41

@LeeJC

#include <stdio.h>
#include <string.h>
char s1[2001],s2[2001];
int i,j,a[2002],b[2002],c[500001];
int main()
{
    scanf("%s %s",s1,s2);
    a[0]=strlen(s1);
    b[0]=strlen(s2);
    for(i=1;i<=a[0];i++)
        a[i]=s1[a[0]-i]-'0';
    for(i=1;i<=b[0];i++)
        b[i]=s2[b[0]-i]-'0';
    for(i=1;i<=a[0];i++)
        for(j=1;j<=b[0];j++)
        // c[i+j-1]=a[i]*b[j];
        // 把=改成+=
        c[i+j-1]+=a[i]*b[j];
    int len=a[0]+b[0];
    for(i=1;i<len;i++)
        if(c[i]>9)
        {
            c[i+1]+=c[i]/10;
            c[i]%=10;
        }
    while(c[len]==0&&len>1) len--;
    for(i=len;i>0;i--) printf("%d",c[i]);
    return 0;
}

|