SPOJ Problem 6:Simple Arithmetics

本文介绍了一种使用C语言实现高精度算术运算的方法,包括加法、减法及乘法,并通过竖式格式输出结果。代码详细展示了如何处理大数运算中涉及的数据结构与算法。

题目大意:给出一个有+、-、*的正整数式子,采用竖式计算并输出答案,答案必定为正数。

高精度问题,有点麻烦,而且格式有很多要注意的。具体可以看

http://blog.youkuaiyun.com/tiaotiaoyly/article/details/2087975

的,而且下面有输入输出的测试数据。

http://contest.felk.cvut.cz/00cerc/solved/arith.in
http://contest.felk.cvut.cz/00cerc/solved/arith.out

我的代码在下面:

#include<cstdio>
#include<cstring>

#define max(a,b)a>b?a:b
char s[1005],r;
int a[505],b[505],c[505],d[505][1005];
int i,j,k,l,n;

void decr(){
    int p,q;
    c[0]=a[0];
    for (i=1;i<=a[0];i++){
        c[i]=c[i]+a[i]-b[i];
        if (c[i]<0){c[i]+=10;c[i+1]--;}
    }
    while(c[0]>1&&c[c[0]]==0)c[0]--;
    p=max(b[0]+1,a[0]);
    q=max(b[0]+1,c[0]);
    for (i=1;i<=p-a[0];i++)printf(" ");
    for (i=a[0];i;i--)printf("%d",a[i]);printf("\n");
    for (i=1;i<=p-b[0]-1;i++)printf(" ");
    printf("-");
    for (i=b[0];i;i--)printf("%d",b[i]);printf("\n");
    for (i=1;i<=p-q;i++)printf(" ");
    for (i=q;i;i--)printf("-");printf("\n");
    for (i=1;i<=p-c[0];i++)printf(" ");
    for (i=c[0];i;i--)printf("%d",c[i]);printf("\n");
}
void incr(){
    int p,i;
    c[0]=max(a[0],b[0]);
    for (i=1;i<=c[0];i++){
        c[i]=a[i]+b[i];
        if (i>1){
            c[i]+=c[i-1]/10;
            c[i-1]%=10;
        }
    }
    if (c[c[0]]>9){c[c[0]]%=10;c[++c[0]]=1;}
    p=max(a[0],b[0]+1);
    if (c[0]>p)p=c[0];
    for (i=1;i<=p-a[0];i++)printf(" ");
    for (i=a[0];i;i--)printf("%d",a[i]);printf("\n");
    for (i=1;i<=p-b[0]-1;i++)printf(" ");
    printf("+");
    for (i=b[0];i;i--)printf("%d",b[i]);printf("\n");
    for (i=p;i;i--)printf("-");printf("\n");
    for (i=1;i<=p-c[0];i++)printf(" ");
    for (i=c[0];i;i--)printf("%d",c[i]);printf("\n");
}

void mult(){
    int p,q,s;
    memset(d,0,sizeof(d));
    d[0][0]=a[0]+b[0]-1;
    for (i=1;i<=b[0];i++){
        d[i][0]=a[0];
        for (j=1;j<=a[0];j++){
            d[i][j]=b[i]*a[j];
            d[0][i+j-1]=d[0][i+j-1]+b[i]*a[j];
            if (i+j>2){
                d[0][i+j-1]+=d[0][i+j-2]/10;
                d[0][i+j-2]%=10;
            }
            if (j>1){
                d[i][j]+=d[i][j-1]/10;
                d[i][j-1]%=10;
            }    
        }
        d[i][++d[i][0]]+=d[i][d[i][0]-1]/10;d[i][d[i][0]-1]%=10;
        while(d[i][0]>1&&!d[i][d[i][0]])d[i][0]--;
    }
    while(d[0][0]>1&&!d[0][d[0][0]])d[0][0]--;
    while(d[0][d[0][0]]>9){d[0][++d[0][0]]=d[0][d[0][0]-1]/10;d[0][d[0][0]-1]%=10;}
    q=max(b[0]+1,d[1][0]);
    p=d[0][0];s=max(p,q);
    for (i=1;i<=s-a[0];i++)printf(" ");
    for (i=a[0];i;i--)printf("%d",a[i]);printf("\n");
    for (i=1;i<=s-b[0]-1;i++)printf(" ");printf("*");
    for (i=b[0];i;i--)printf("%d",b[i]);printf("\n");
    for (i=1;i<=s-q;i++)printf(" ");for (i=1;i<=q;i++)printf("-");printf("\n");
    for (i=1;i<=b[0];i++){
        for (j=1;j<=s-d[i][0]-i+1;j++)printf(" ");
        for (j=d[i][0];j;j--)printf("%d",d[i][j]);
        printf("\n");
    }
    if (b[0]>1){
        for (i=1;i<=s-p;i++)printf(" ");
        for (i=p;i;i--)printf("-");printf("\n");
        for (i=1;i<=s-d[0][0];i++)printf(" ");
        for (i=d[0][0];i;i--)printf("%d",d[0][i]);printf("\n");
    }
}
int main(){
    //freopen("s.in","r",stdin);
    //freopen("p.out","w",stdout);
    scanf("%d",&n);
    while(n--){
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        memset(d,0,sizeof(d));
        scanf("%s",s);
        l=strlen(s);i=0;
        while(s[i]!='+'&&s[i]!='-'&&s[i]!='*')i++;r=s[i];
        a[0]=i; b[0]=l-i-1;    
        for (j=0;j<i;j++)a[i-j]=s[j]-48;
        for (j=i+1;j<l;j++)b[b[0]-j+i+1]=s[j]-48;
        if (r=='+')incr();
        else if (r=='-')decr();
        else mult();
        printf("\n");
    }
}

 

转载于:https://www.cnblogs.com/moris/p/4306120.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值