• poj1503---大数加法


    先讲一种错误的做法:WA了n次,大神一定帮我看一下//看到有说数组大小开到250,我改了之后还是不//思路是将arr这个数组的每一行附上输入的值,然后求每列所有数之和,当然进位

    //maxlen记录这个二维数组的有用就是可以加的长度列数,row用来记录行数,那就不用遍历二维数组所有行列
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    int main()
    {
        char tempArr[250];
        int arr[250][250],fin[250],i,row=0,maxlen=0,column;
        /*下面这个while循环用来把每次输入的字符串先放在tempArr里,然后转换,放到arr里面*/
        while(scanf("%s",tempArr)!=EOF)
        {
            int len;
            len=strlen(tempArr);
            column=249;
            if(tempArr[0]=='0' &&len==1)
                break;
            for(i=len-1;i>=0;i--)
            {
                arr[row][column]=tempArr[i]-'0';//arr每一行最后几列用来存数字
                column--;
            }
            row++;//row记录行数
            if(maxlen<len)
            {
                maxlen=len;//记录输入的数中那个数的长度最长
            }
        }
        /*下面就是大数加法的算法实现*/
        int temp=0,index=249;
        for(column=249;column>(247-maxlen);column--)//从最后一列开始加
        {//估计最多进两位,所以循环出去的条件我就随便写了,下面有跳过前导0的
            int columnSum=0;
            for(i=0;i<row;i++)
            {
                columnSum+=arr[i][column];
            }
            fin[index]=(columnSum+temp)%10;//对这个数组的赋值也是从fin最后开始的
            temp=(columnSum+temp)/10;
            index--;
        }
        //得到第一个不为0的fin下标,从左至右
        while(fin[index]==0){
            index++;
         if(index=250)
          break;
      }
      if(index==250)
        printf("%d",0);
      else{
    //从哪个位置开始输出 for(i=index;i<=249;i++) { printf("%d",fin[i]); } printf(" ");
      } return 0; }

      大致思路:复用tempArr,第一个while循环用来分别给arr的各行赋值,以row来记录二维数组实际行数

    分别从最后几列开始赋值,一直赋到tempArr中没有元素,i=0,第二个块用来给每一列求和,纠结一点的:

    for(column=249;column>(247-maxlen);column--)//从最后一列开始加
        {//估计最多进两位,所以循环出去的条件我就随便写了,下面有跳过前导0的
            int columnSum=0;
            for(i=0;i<row;i++)
            {
                columnSum+=arr[i][column];
            }
            fin[index]=(columnSum+temp)%10;//对这个数组的赋值也是从fin最后开始的
            temp=(columnSum+temp)/10;
            index--;
        }
    

      原想求得row,求得len,不用遍历整个数组

    比如:246    247   248    249      len=4,249-maxlen:249-4=245,两个for循环,第一个for用来循环列,比如1+9999,当列固定在246列时,循环弹出来了,fin[246]得0,temp=1,如果用column>249-maxlen=245,1就没得到进位,类似:

     while(temp>0)
            {
                int c;
                c=temp+fin[j];
                temp=c/10;
                fin[j]=c%10;
                j++;
            }

    我没用这个方法,我把遍历范围放的尽量大,但是最多进两位,所以247-maxlen应该是合理的了,还是不行,我开到遍历完每一列,也不行,求解?

    第二种方法:

    始终保持一个fin数组用来放结果,每次的输入放在input中,memset下fin为0,将input数组从右往左,分别加到fin的第一个,第二个..元素,搜获到的技巧:

    for(i=len-1,j=0;i>=0;i--,j++)

    for循环上写两个变量的初值及变化,增加可读性

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    int main()
    {
        char input[101];
        int fin[104]={0};
        int len,temp,i,j;
        while(scanf("%s",input)!=EOF)
        {
            if(input[0]=='0' && strlen(input)==1)
                break;
            len=strlen(input);
            temp=0;
            for(i=len-1,j=0;i>=0;i--,j++)//循环跳出条件input数组取到第一个元素
            {
                int c;
                c=input[i]-'0'+fin[j]+temp;
                temp=c/10;
                fin[j]=c%10;
            }
         //循环结束后,j++此时为finde下一个待决定位
      //处理字符串读完,但是仍有进位的情况
    while(temp>0) { int c; c=temp+fin[j]; temp=c/10; fin[j]=c%10; j++; } } i=103;
        //倒序输出,去掉前导0,fin里面可能全是0,i此时为-1,输出0
    while(fin[i]==0)//000+00 { i--;
            //网上没有if这个步奏,但我觉得会溢出之类的
    if(i==-1) break; } if(i<0) printf("%d ",0); else { for(;i>=0;i--) { printf("%d",fin[i]); } printf(" "); } return 0; }

    总结:这题坑在000+00,999+1

    收获:int 数组,将第一个以int a[5]={1},可将第一个元素赋为0,其余元素为0

    char就不行,应该是编译器决定的,所以gcc最好memset,但是以上都仅限scanf

    如果用赋值,最好memset

    第三种:看不懂

    http://www.slyar.com/blog/poj-1503-c.html

  • 相关阅读:
    第一章-实例7-猴子吃桃问题
    第一章-实例6-判断是否为闰年
    第一章-实例3-计算变量所占字节数
    IDEA学习笔记
    spring boot学习概要(尚硅谷)
    JSP动态WEB开发技术--第一章
    学习前端的准备任务
    cmd优化
    软件测试基础概念
    软件工程理论
  • 原文地址:https://www.cnblogs.com/gabygoole/p/4479890.html
Copyright © 2020-2023  润新知