UVA 424和10106的个人体会

【高精度计算】

     今天是开博客的第一天,特此庆祝一下,也激励一下自己要更加努力。机会总是留给勤奋努力的人的。从今天开始我希望在博客中记录自己刷OJ的一些感想和体会 ,现在自己还很一般,希望通过博客记录自己成长的一点一滴。

    今天开始我会研究关于高精度计算的相关题目。刚刚做了两道题,现在一一贴出来。

  1. UVA 424 Integer Inquiry

        高精度求和:

        输入:每行输入一个不超过100位的数字,当输入为0时输入结束

        输出:各行数字的和


分析:看到这道题目,立马可以想到要想表示100位的数字,int 和long long都是无法完成的。为了要完成任务,我们可以想到使用数组或者字符串。数组的优点是:数组的各位可以任意进行计算,但是数组的输入不方便,需要用空格等间隔开;而字符串的优点恰好相反,字符串的输入十分方便,但是按位进行计算比较麻烦。因此,我们可以采用以字符串的方式进行输入,最后将输入的字符串按位转化为数组中的元素进行运算。

其中需要注意的就是相加函数的编写。在该程序中,将数组第一个元素定义为数字长度。主要是使用按位相加,最终根据每一位是否大于等于10 来进行进位操作。

代码:

#include <stdio.h> 
#include <stdlib.h>
#include <string.h>
char s[120][120];
int number[120][120]; //数组最好开得大一些
void add(int number1[],int number2[])
{
    if(number1[0]<number2[0])
        number1[0]=number2[0];        //保证number1是更大的,因为最终的结果要保存在number1中
    int i;
    for(i=1;i<=number1[0];i++)
    {
        number1[i]+=number2[i];       //每一位都各自相加
        if(number1[i]>=10)
        {
            number1[i+1]+=number1[i]/10;  //如果某一位大于等于10 就要进位
            number1[i]%=10;
        }
    }
    if(number1[number1[0]+1]>0)         //最后判断最高位是否产生进位,如果进位了,就要在记录长度的元素加1
        number1[0]++;
}
int main()
{
    int i=0,j,k;
    while(scanf("%s",s[i])!=EOF)             
    {
        if(strcmp(s[i],"0")==0)     //这里是代表输入为0时自动跳出循环,结束输入
        {
            break;
        }
        i++;
    }
    for(j=0;j<i;j++)
    {
        number[j][0]=strlen(s[j]);   //将数组的第一个元素记录字符串的长度
        for(k=1;k<=number[j][0];k++)
            number[j][k]=s[j][number[j][0]-k]-'0';  //将字符串的每一位字符转化为整数赋值给数组,但是要注意最好采用倒序赋值,因为在数组运算会产生进位
                                                    //利用倒序会很方便
 }
    for(j=1;j<i;j++)
        add(number[0],number[j]);          //进行相加,值存放在number[0]中
    for(j=number[0][0];j>=1;j--)
        printf("%d",number[0][j]);         //逆序打印输出
    printf("\n");
    return 0;
}


解题的时候,我出现了一个问题:

在第一次上交OJ时,出现了WA,主要是粗心,因为当时使用了freopen重定向至文本输入,判断完成时没有删除就提交了。

最后删除过后再提交就AC了。


         2. UVA 10106 Product

           乘积.

           输入:两个整数x,y,(0<=x,y<10^250)

           输出:两个数的积.

分析:这道题由于是要求250位的乘积,所以依然要用到高精度,分析当时类似于上题


代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char s[10][300];
int str[10][300];
int res[600];
void mutiply(int *a,int *b)
{
    memset(res,0,sizeof(res));
    if((a[0]==1&&a[1]==0)||(b[0]==1&&b[1]==0))   //如果有一个数是0的话,结果就是0,退出函数
    {
        res[0]=1;
        res[1]=0;
        return;
    }
    int i,j;
    for(i=1;i<=a[0];i++)
        for(j=1;j<=b[0];j++)
            res[i+j-1]+=a[i]*b[j];     //两个数相乘,先按位进行相乘
    res[0]=a[0]+b[0]-1;                //最后的长度为两个数字长度之和减1   
    for(i=1;i<=res[0];i++)
    {
        if(res[i]>=10)              //如果某一位大于等于10,就进位
        {
            res[i+1]+=res[i]/10;
            res[i]%=10;
        }
    }
    while(res[res[0]+1]>0)
        res[0]++;
    return;
}
int main()
{
    memset(s,0,sizeof(s));    //将数组置0
    int i=0;
    while(fgets(s[i],sizeof(s[i]),stdin)!=NULL)
    {
        int j;
        str[i][0]=strlen(s[i])-1;
        for(j=1;j<=str[i][0];j++)
        {
            str[i][j]=s[i][str[i][0]-j]-'0';
        }
        i++;
        if(i==2)
        {
            mutiply(str[0],str[1]);    //相乘,结果赋值给res 
            for(j=res[0];j>=1;j--)
                printf("%d",res[j]);
            printf("\n");
            i=0;
            memset(s,0,sizeof(s));
        }
    }
    return 0;
}

解题时,第一次提交给OJ时出现WA,主要原因是没有对输入的数字是0进行判断,如果输入1234*0,按照我的思路结果是0000,与答案不符。所以必须在计算前进行判断,如果是0的话就直接退出即可。

第二次提交时就AC了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值