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\n",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   ,看到这的都是真爱啊,那么,不妨心中怀着这个公式从头再来一遍吧,相信这遍,会更清晰。

 

posted on 2016-04-13 18:30  逸阳  阅读(203)  评论(0编辑  收藏  举报

导航