n!:尾数为1,不会影响结果,2和5会影响,先统计2 和 5的个数 递归不断ans+=n/(2,5) 可以得到
,因为尾数为3,7的他们自己不断相乘是一个循环节,3: 3-9-7-1, 7: 7-9-3-1;
所以现在统计,因数尾数 3 和 7 的个数,
如有1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
3的个数这里看有3个 分别是3 和13 但是 15/5之后也有3。。
而且:偶数除2之后又是递归了一半,所以有getx(n,x)=getx(n/2,x)+get(n,x);
get(n,x)就是在奇数当中统计x的个数了,因为这些奇数中又有可以被5除的数
所以get(n,x)=get(n/5,x)+n/10+(n%10>=x);
#include <iostream>
#include <cstdio>
using namespace std;
int p[20000010];
int mp[3][4]={
6,2,4,8,
1,3,9,7,
1,7,9,3
};
int get2(int n);
int get5(int n);
int getx(int n,int x);
int get(int n,int x);
int main()
{
int n,m,res;
while(scanf("%d%d",&n,&m)!=EOF)
{
res=1;
int num5=get5(n)-get5(n-m);
int num2=get2(n)-get2(n-m);
int num3=getx(n,3)-getx(n-m,3);
int num7=getx(n,7)-getx(n-m,7);
// cout<<getx(n,7)<<endl;
num3+=2*(getx(n,9)-getx(n-m,9));
if(num5>num2)
{
printf("5\n");
continue;
}
if(num2-num5>0)
res=res*mp[0][(num2-num5)%4];
res=res*mp[1][num3%4]%10;
res=res*mp[2][num7%4]%10;
printf("%d\n",res);
}
return 0;
}
int get2(int n)
{
if(n==0) return 0;
return get2(n/2)+n/2;
}
int get5(int n)
{
if(n==0) return 0;
return get5(n/5)+n/5;
}
int getx(int n,int x)
{
if(n==0) return 0;
return getx(n/2,x)+get(n,x);
}
int get(int n,int x)
{
if(n==0) return 0;
return get(n/5,x)+n/10+(n%10>=x);
}
/*
n!:尾数为1,不会影响结果,2和5会影响,先统计2 和 5的个数 递归不断ans+=n/(2,5) 可以得到
,因为尾数为3,7的他们自己不断相乘是一个循环节,3: 3-9-7-1, 7: 7-9-3-1;
所以现在统计,因数尾数 3 和 7 的个数,
如有1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
3的个数这里看有3个 分别是3 和13 但是 15/5之后也有3。。
而且:偶数除2之后又是递归了一半,所以有getx(n,x)=getx(n/2,x)+get(n,x);
get(n,x)就是在奇数当中统计x的个数了,因为这些奇数中又有可以被5除的数
所以get(n,x)=get(n/5,x)+n/10+(n%10>=x);
*/