The Last Non-zero Digit
Time Limit: 1000MS |
|
Memory Limit: 65536K |
Total Submissions: 3156 |
|
Accepted: 850 |
Description
In this problem you will be given two decimal integer number N, M. You will have to find the last non-zero digit of the N P M .This means no of permutations of N things taking M at a time.
Input
The input contains several lines of input. Each line of the input file contains two integers N (0 <= N<= 20000000), M (0 <= M <= N).
Output
For each line of the input you should output a single digit, which is the last non-zero digit of N P M . For example, if N P M is 720 then the last non-zero digit is 2. So in this case your output should be 2.
Sample Input
10 10
10 5
25 6
Sample Output
8
4
2
Source
uva 10212
求n!/(n-m)! 的最后一位不是 0 的数。
先想想如何求一个数的阶乘n !的最后一位不是 0 的数,由于 0 只可能由 2*5 得出,所以算出因子为 2 的个数和因子为 5 的个数。显然对于一个阶乘来说 2 的因子个数显然大于等于 5 的个数。然后再求出末尾是 3,7,9 和除以 2,5 之后末尾是 3,7,9 的个数。
对于10 !: 1 2 3 4 5 6 7 8 9 10
2的因子个数为 10/2+10/4+10/8
5的因子个数为 10/5
然后将这十个数分成奇数和偶数
1 3 5 7 9 2 4 6 8 10
将偶数部分除以2 之后又成为了 1,2,3,4,5 ,而 2 我们已经处理掉了,所以就有如下递归
F(int x,int t)
{
Return F(x/2,t)+g(x,t);//其中 g 为处理奇数中末尾的处理函数。
}
而奇数又要考虑到因数5 ,所以又把奇数分成了两部分
1,3,7,9,11,13,17,19 5,15,
就是末尾是5 的和末尾不是 5 的,其中末尾是 5 的除以 5 之后又是 1,3,5,7,9 ……
所以又是一个递归。
具体详见代码。
#include <stdio.h> int num[10]; int map[4][4]= { 6,2,4,8, 1,3,9,7, 1,7,9,3, 1,9,1,9, }; int Countnum(int x,int t) { if (x==0) return 0; return x/10+(x%10>=t)+Countnum(x/5,t); } int Count(int x,int t) { if (x==0) return 0; return Count(x/2,t)+Countnum(x,t); } int Getnum(int x,int t) { if (x==0) return 0; return x/t+Getnum(x/t,t); } void SubCount(int x) { int two,five; two=Getnum(x,2); five=Getnum(x,5); num[2]=num[2]-two+five; num[3]-=Count(x,3); num[7]-=Count(x,7); num[9]-=Count(x,9); } void AddCount(int x) { int two,five; two=Getnum(x,2); five=Getnum(x,5); num[2]=num[2]+two-five; num[3]+=Count(x,3); num[7]+=Count(x,7); num[9]+=Count(x,9); } int main() { int m,i,j,n,ans; while(scanf("%d%d",&n,&m)!=EOF) { for (i=0;i<10;i++) { num[i]=0; } AddCount(n); SubCount(n-m); ans=1; if (num[2]!=0) ans=ans*map[0][num[2]%4]%10; if (num[3]!=0) ans=ans*map[1][num[3]%4]%10; if (num[7]!=0) ans=ans*map[2][num[7]%4]%10; if (num[9]!=0) ans=ans*map[3][num[9]%4]%10; printf("%d/n",ans); } return 0; }