poj 1150 The Last Non-zero Digit
#include<iostream> // 求 n! / (n-m)! 最后一个非0位
#include<cmath>
using namespace std;
int get2(int n) //计算n!中质因子2的出现次数
{
if(n==0)
return 0;
return n/2+get2(n/2);
}
int get5(int n) ////计算n!中质因子5的出现次数
{
if(n==0)
return 0;
return n/5+get5(n/5);
}
int g(int n,int x) //计算f(1) to f(n) 中,奇数数列中末尾为x(1,3,7,9)的数出现的次数
{
if(n==0)
return 0;
return n/10+(n%10>=x)+g(n/5,x);
}
int getx(int n,int x) ///计算f(1) to f(n)中,末尾为x的数的出现次数
{
if(n==0)
return 0;
return getx(n/2,x)+g(n,x);
}
//利用两个递归方程getx(),g(),我们就可以在lgn的时间内计算出末尾为1,3,7,9的数的个数了,而在求n!中质因子2,5的出现次数所用时间同样是lgn
int main()
{
int n,m,num2,num3,num5,num7,num9;
while(cin>>n>>m)
{
num2=get2(n)-get2(n-m);
num5=get5(n)-get5(n-m);
if(num2<num5) //说明只有一个数字,并且它的末位为5
printf("5\n");
else
{
num3=getx(n,3)-getx(n-m,3);
num7=getx(n,7)-getx(n-m,7);
num9=getx(n,9)-getx(n-m,9);
num3%=4;num7%=4;num9%=4;
num2-=num5;
while(num2>=5)
{
num2=num2/5+num2%5;
}
printf("%d\n",int(pow(2.0,num2)*pow(3.0,num3)*pow(7.0,num7)*pow(9.0,num9))%10);
}
}
return 0;
}
//http://www.cppblog.com/abilitytao/archive/2010/08/11/99907.html