poj1150 The Last Non-zero Digit

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);
*/

猜你喜欢

转载自blog.csdn.net/hyacinthhome/article/details/81486811