• Uva 10494 If We Were a Child Again(大数相除)


    Problem C
    If We Were a Child Again
    Input: standard input
    Output: standard output
    Time Limit: 7 seconds

     


    “Oooooooooooooooh!
    If I could do the easy mathematics like my school days!!
    I can guarantee, that I’d not make any mistake this time!!”
    Says a smart university student!!
    But his teacher even smarter – “Ok! I’d assign you such projects in your software lab. Don’t be so sad.”
    “Really!!” - the students feels happy. And he feels so happy that he cannot see the smile in his teacher’s face.

    The Problem

    The first project for the poor student was to make a calculator that can just perform the basic arithmetic operations.

    But like many other university students he doesn’t like to do any project by himself. He just wants to collect programs from here and there. As you are a friend of him, he asks you to write the program. But, you are also intelligent enough to tackle this kind of people. You agreed to write only the (integer) division and mod (% in C/C++) operations for him.

    Input
    Input is a sequence of lines. Each line will contain an input number. One or more spaces. A sign (division or mod). Again spaces. And another input number. Both the input numbers are non-negative integer. The first one may be arbitrarily long. The second number n will be in the range (0 < n < 231).



    Output
    A line for each input, each containing an integer. See the sample input and output. Output should not contain any extra space.



    Sample Input
    110 / 100
    99 % 10
    2147483647 / 2147483647
    2147483646 % 2147483647






    Sample Output
    1
    9
    1
    2147483646

      1 #include<stdio.h>
      2 #include<string.h>
      3 #define MAXN 1002
      4 int a[MAXN], c[MAXN], last[MAXN]; // a是存储整型的被除数,c是存储得数,last存储的是每次相除后(其实是相减)的余数 
      5 char s[MAXN]; //存储输入的被除数 
      6 
      7 int dealb(int (*b)[20], char *d)
      8 {// 求出 除数*n 的每个值并存于数组b中(n = 1 2 3 4 ..... 9) 
      9     int len = strlen(d), i, j, e, temp, t;
     10     for(i=0; i<len; ++i)
     11     for(j=1; j<10; ++j)
     12     b[j][i+1] = d[len-1-i] - '0';
     13     b[1][0] = len;
     14 
     15     for(i=2; i<10; i++)
     16     {//大数相乘 
     17         e = 0;
     18         for(t=1; t<len+1; ++t)
     19         {
     20             temp = i*b[i][t] + e;
     21             b[i][t] = temp%10;
     22             e = temp/10;
     23         }
     24         if(e) b[i][t++] = e;
     25         b[i][0] = t-1;
     26     }
     27     return 0;
     28 }
     29 
     30 int cmp(int (*b)[20], int n)
     31 {// 从上到下筛选dealb函数得到的数组,返回的值是得数的依次低位数,
     32  //n存储的是余数数组或者说除数依次高位向下的数个数和最高下标 
     33     int i, j, temp, t, k, flag;
     34     for(k=0; k<n && last[k]==0; ++k);
     35     for(i=9; i>0; --i)
     36     {
     37         // 两个数比较的三种情况 
     38         if(b[i][0] > n-k+1) continue;  // 位数不相同情况之一,减数较大则继续找下一位 
     39         if(b[i][0] < n-k+1) return i;  // 位数不相同情况之二,减数较小则返回减数的所在的下标,这个值也是得数的当前最低位数 
     40         for(j=b[i][0],t=k,flag=0; t<=n && j>0 && b[i][j] == last[t]; ++t, --j) //位数相同的,逐个位权的数进行比较 
     41             ;
     42         if(t>n || j<=0 || b[i][j] < last[t]) return i;
     43     }
     44     return 0;
     45 }
     46 
     47 int main()
     48 {
     49     int i, j, k, t, len, flag, temp, count = 0, loc, e, h;
     50     int  b[12][20]; // b[i]存储的除数*i的值(i=1 2 3...9),每个第一位即b[i][0]存储该值的长度 
     51     char opt, d[20];
     52     while(scanf("%s", s) != EOF)
     53     {
     54         while((opt = getchar()) == ' ');
     55         scanf("%s", d);
     56         dealb(b, d);
     57         len = strlen(s);
     58         for(i=0; i<len; ++i) a[i] = s[i] - '0';
     59         count = loc = h = 0;
     60         for(i=0; i<len; ++i)
     61         {
     62             last[count++] = a[i];
     63             if((loc = cmp(b, count-1)) != 0)
     64             {
     65                 for(t=count-1,j=1,e=0; t>=0 && j<=b[loc][0]; --t, ++j)
     66                 {// 从cmp得到的信息保证了b[1oc] - last >=0,此处进行相减运算 
     67                     if((temp = last[t]-b[loc][j] + e) < 0)
     68                     {
     69                         e = -1;
     70                         last[t] = 10 + temp;
     71                     }
     72                     else
     73                     {
     74                         e = 0;
     75                         last[t] = temp;
     76                     }
     77                 }
     78                 if(j>b[loc][0] && t>=0)
     79                 {
     80                     for(; t>=0; --t)
     81                     {
     82                         temp = last[t] + e;
     83                         if(temp < 0) e = -1, last[t] = 10+temp;
     84                         else e = 0, last[t] = temp;
     85                     }
     86                 }
     87                 
     88             }
     89             c[h++] = loc;
     90         }
     91         if(opt == '/')
     92         {
     93             for(i=0; i<h-1 && c[i] == 0; ++i);   // 除去前缀零 
     94             for(; i<h; ++i) printf("%d", c[i]);
     95         }
     96 
     97         else 
     98         {
     99             for(i=0; i<count-1 && last[i] == 0; ++i);
    100             for(; i<count; ++i)printf("%d", last[i]);
    101         }
    102         printf("\n");
    103     }
    104     return 0;
    105 }

    1Wa

    解题思路:

    大数的运算主要是根据笔算的步骤用代码实现,不管是乘法、加法、减法都不例外,下面说说大数相除的思路:

    变量声明:

    便于理解,首先为每个变量设一个字符(根据我的代码)

    被除数:a (存储从左至右 即 xxx... = a[0]a[1]a[2]....)

      除数:b[1] (存储从右至左 即 xxx... = b[1][n]b[n-1][n-2]... 长度n=b[1][0])同样可以理解 b[m](m = 1 2 3 4...9) = b[1] * m;   

        商: c (存储从左至右 即xxx... = c[0][1][2]...)输出时应该省略掉前缀无意义的0

    余数/次被除数:last (存储从左至右 ) 根据除法的运算可知,每次要得到商上的一个数字时,都要进行一次减法的运算,有时得到的0,有时得到的小于除数的值,而到最后时它的    身份是余数而已; 同时,每次得到商的一个数字时,如果last有非零数时,它必须再和被除数的下一权值上的数进行组合(运算)可描述为:last = last*10 + n 然后进行相除

    步骤:

    1.  根据除数求出 1~9倍的数

    2. 开始截取被除数的高到低的位数并存储到last数组中,比如说 a = 1234 则第一次截取的数为last = 1,在cmp函数中找到需要的那个数(其实也是商中所对应的位置的值),比如说设除数 b1 = 10; 则 b2 = 20, b3 = 30 ... b9 = 90; 从b9->b1从高到低找,直到找到 last - bn > 0 且最接近0的那个数bn,并返回n,这时保证了符合两数相减且合适差最小的条件

    3. 将返回的n存储到商中,并进行第2步说的相减运算,将差放入余数last中

    4. 在除数中继续截取目前高位的数字,这次是 a 中的 2,并接到last值得后面,变成次被除数last,这时last的值变成 12 ,然后继续调用cmp函数, 即转到步骤2,继续运算求值

    5. 最后根据题目要求输出需要printf的值,输出时省略无意义的0

  • 相关阅读:
    679 怎样杀死害虫?(对付一个系统最好的方式是“围城必阙”)
    678 "流浪地球"为什么是个好地方?(系统越复杂拥有好运气的机会也就越大)
    677 人类为什么会养猫?(做一件事理性的原因的背后往往还隐藏着自己都不曾发现的感性原因)
    职场人必知的三原则
    677 怎样当一个少数派?(越在意,越出众)
    675 为什么会有“黑天鹅”?(行为和对行为后果的负责与否决定了很多黑天鹅出现概率)
    不做特殊论者(没有所谓的理所当然,你所谓的成功很有可能只是因为运气)
    事实和观点(就事论事,事实有真假,观点无对错)
    一个程序员的价值观总结
    669 创新也是搞政治?(如何创新)
  • 原文地址:https://www.cnblogs.com/liaoguifa/p/2839484.html
Copyright © 2020-2023  润新知