• NYOJ 485


    A*B Problem

    描述

    设计一个程序求出A*B,然后将其结果每一位相加得到C,如果C的位数大于等于2,继续将C的各位数相加,直到结果是个一位数k。

    例如:

    6*8=48;

    4+8=12;

    1+2=3;

    输出3即可。

    输入
    第一行输入一个数N(0<N<=1000000),表示N组测试数据。
    随后的N行每行给出两个非负整数m,n(0<=m,n<=10^12)。
    输出
    对于每一行数据,输出k。
    样例输入
    3
    6 8
    1234567 67
    454 1232
    样例输出
    3
    4
    5

    这道题目和之前的 http://www.cnblogs.com/liugl7/p/5362552.html 很像,在那道题中就总结了一个规律,就是:一个大数对9取余等于这个数各位数字之和对9取余。现在根据这个题目的意思,是反过来了。题目中说,这个数的各个位的数字之和一直处理到个位数。  我们经过演算可以得知计算“一个数W=mn的这样的运算”的结果可以用(W-1)%9+1直接得到。

    而 mn-1 = (m-1 +1)(n-1 +1)-1 = (m-1)(n-1)+(m-1) + (n-1)+1 - 1 = (m-1)(n-1)+(m-1) + (n-1)

    所以(mn-1)%9 = [(m-1)(n-1)+(m-1) + (n-1) ]%9 = [(m-1)(n-1)%9+(m-1)%9 + (n-1)%9]%9= { [(m-1)%9+1] * [(n-1)%9+1]  -1   }%9

    即 结果A=  (mn-1)%9 +1 =  { [(m-1)%9+1] * [(n-1)%9+1]  -1   }%9 +1 

      这样就把m和n的位数降下来了,可以直接输入m、n然后对9取模; 如果遇到了long long 存不下的数,可以运用http://www.cnblogs.com/liugl7/p/5362552.html 中的处理方法,充分运用10X≡9X+X≡X(mod 9)来完成 m%9和n%9的运算。

    AC代码如下:

     1 #include<stdio.h>
     2 int main(){
     3     long long m,n;
     4     int temp,ans,t;
     5     scanf("%d",&t);
     6     while(t--){
     7         scanf("%lld%lld",&m,&n);
     8         temp = ( (m-1)% 9+1) * ( (n-1)%9+1);
     9         ans = (temp-1)% 9+1;
    10         printf("%d
    ",ans);
    11     }
    12     return 0;
    13     
    14 }

    不过需要mark的是“9余数定理”这个东西,【一个数的各位数字之和想加后得到的<10的数字称为这个数的九余数(如果相加结果大于9,则继续各位相加)】9余数定理的其中一条有:两个因数的九余数相乘,所得的数的九余数应当等于两个因数的乘积的九余数。关于这个“9余数”,还有一个比较好玩的应用是计算“从1到1024排成一个数除以9,余数是多少?”  http://www.zhihu.com/question/26033918

    这里面充分应用了10X≡9X+X≡X(mod 9)这个性质,顺带手还有9余数定理的体现。

    经过本题,我们可以发现  计算一个数W的9余数的公式是  (W-1)%9+1   ,看到这的都是真爱啊,那么,不妨心中怀着这个公式从头再来一遍吧,相信这遍,会更清晰。

  • 相关阅读:
    bzoj2946 [Poi2000]公共串(SA,SAM)
    77 最长公共子序列
    C++ lower_bound 与 upper_bound 函数
    76 最长上升子序列
    75 寻找峰值
    C++标准输入问题
    74 第一个错误的代码版本
    73 前序遍历和中序遍历树构造二叉树
    72 中序遍历和后序遍历树构造二叉树
    71 二叉树的锯齿形层次遍历
  • 原文地址:https://www.cnblogs.com/liugl7/p/5388281.html
Copyright © 2020-2023  润新知