The Intersting Digit

The Intersting Digit

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 3
描述
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 NPM.This means no of permutations of N things taking M at a time.
输入
The input contains several lines of input. Each line of the input file contains two integers N (0 <= N<= 20000000), M (0 <= M <= N).
输出
For each line of the input you should output a single digit, which is the last non-zero digit of NPM. For example, if NPM is 720 then the last non-zero digit is 2. So in this case your output should be 2.
样例输入
10 10
10 5
25 6
样例输出
8
4
2
来源

poj

这个题求的是c(n, m)的最后一个非零数, 但实际上求的是n!/(n-m)! 的最后一位非零数(汗-_-|||)详情可见网上的解释(poj1150), 就是求2, 3, 5, 7, 9的个数来简化计算, 数论的题。。。

解释

#include <stdio.h>
#include <math.h>

int get2(int n)
{
    if(n == 0)
    {
        return 0;
    }
    return n/2+get2(n/2);
}

int get5(int n)
{
    if(n == 0)
    {
        return 0;
    }
    return n/5+get5(n/5);
}

int getxfromodd(int n, int x)      //求n!的 奇序列中找3, 7, 9的个数
{
    if(n == 0)
    {
        return 0;
    }
    return n/10 + (n%10 >= x) + getxfromodd(n/5, x);  //5, 15, 25, 35中也有3, 7, 9
}

int getx(int n, int x)
{
    if(n == 0)
    {
        return 0;
    }
    return getxfromodd(n, x)+getx(n/2, x);    //先从奇数序列, 再从偶数序列中找3, 7, 9
}

int circle[4][4] = {   //2, 3, 7, 9的n次方循环节
    6, 2, 4, 8,     //2
    1, 3, 9, 7,     //3
    1, 7, 9, 3,     //7
    1, 9, 1, 9      //9
};

int main()
{
    /*for(int i = 0; i < 4; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            printf("%d ", circle[i][j]);
        }
        printf("\n");
    }*/
    int n, m, num2, num3, num5, num7, num9, res;
    while(scanf("%d%d", &n, &m) != EOF)
    {
        res = 1;
   /*     num2 = get2(n)-(get2(m)+get2(n-m));
        num5 = get5(n)-(get5(m)+get5(n-m));
        num3 = getx(n, 3)-(getx(m, 3)+getx(n-m, 3));
        num7 = getx(n, 7)-(getx(m, 7)+getx(n-m, 7));
        num9 = getx(n, 9)-(getx(m, 9)+getx(n-m, 9));*/
        num2 = get2(n) - get2(n-m);
        num5 = get5(n) - get5(n-m);
        num3 = getx(n, 3) - getx(n-m, 3);
        num7 = getx(n, 7) - getx(n-m, 7);
        num9 = getx(n, 9) - getx(n-m, 9);
      //  printf("%d %d %d %d %d\n", num2, num3, num5, num7, num9);
        if(num5 > num2)            //若5的个数大于2的, 结果为5
        {
            printf("5\n");
            continue;
        }
        else                      //否则另算
        {
            if(num2 != num5)      //2^0为1但2^4为6, 需另算
            {
                res *= circle[0][(num2-num5)%4];
                res %= 10;
            }
            res *= circle[1][num3%4];
            res %= 10;
            res *= circle[2][num7%4];
            res %= 10;
            res *= circle[3][num9%4];
            res %= 10;
            printf("%d\n", res);
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值