• poj 1150 The Last Non-zero Digit


    The Last Non-zero Digit
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 5363   Accepted: 1642

    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 NPM.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 NPM. For example, if NPM 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 Output8

    4
    2

    题意:求A(n,m)的最后一个非零末尾,A(n,m)即n!/(n-m)!
    思路:先把A(n,m)中的所有2和5因子提取出来,考虑剩余部分的积的末尾,这可以表示为A(n,m)/(2^a*5^b)
    ,其中a,b为2,5的因子个数,那么剩余部分的因子结尾一定为3,7,9,可以先把这部分的乘积的末尾求出来(3,7,9的n次方的末尾数都是4个1循环,方便求得),之后再结合因子2和5,若5的个数多于2,最终结尾一定为5,若2的个数多于5,多出来的2^(a-b)
    末尾也是4个数一循环,可以方便求出来。

    那么现在的关键是如何求得因子结尾是3,7,9的那些数的个数,我么可以将n!分成两个数列,奇数列和偶数列,先看奇数列,奇数列中每间隔10都会出现一个3,7,9的数,最后间隔小于10的部分则考虑剩余部分间隔是否大于x(3,7,9),若x大于间隔,则存在一个以x结尾的因子.考虑到数列中有5的倍数,n/5递归数列继续以上的操作。
    偶数列不断递归除以2也能得到奇数列。
    AC代码:


    #define _CRT_SECURE_NO_DEPRECATE
    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    #include<set>
    #include<string>
    #include<queue>
    #include<cmath>
    using namespace std;
    #define INF 0x3f3f3f3f
    const int N_MAX = 20000000+4;
    int n,m;
    //计算n!中x的因子个数
    int prime_num(int n, int x) {
        int num = 0;
        while(n) {
            num += n / x;
            n /= x;
        }
        return num;
    }
    //计算n!以3,7,9结尾的因子的个数
    int odd_end_with(int n,int x) {
        if (n == 0)return 0;
        return n / 10 +((n%10)>=x)+odd_end_with(n / 5, x) ;
    }
    int end_with(int n,int x) {
        if (n == 0)return 0;
        return odd_end_with(n,x) + end_with(n/2,x);
    }
    int table[4][4] = {
      6, 2, 4, 8,//2
      1, 3, 9, 7,//3
      1, 7, 9, 3,//7
      1, 9, 1, 9//9
    };
    
    
    int main() {
        while (scanf("%d%d",&n,&m)!=EOF) {
            int two = prime_num(n, 2) - prime_num(n - m, 2);
            int five = prime_num(n, 5) - prime_num(n - m, 5);
            if (five > two) { printf("5
    "); continue; }
    
            int three = end_with(n, 3) - end_with(n - m, 3);
            int seven = end_with(n, 7) - end_with(n - m, 7);
            int nine = end_with(n, 9) - end_with(n - m, 9);
            int res = 1;
            if(two>five)res *= table[0][(two - five) % 4];
            res *= table[1][three % 4];
            res *= table[2][seven % 4];
            res *= table[3][nine % 4];
            res %= 10;
            printf("%d
    ",res);
        }
        return 0;
    }
  • 相关阅读:
    Matlab——m_map指南(4)——实例
    Python——matplotlib基础绘图函数示例
    Python——Matplotlib库入门
    Python——图像手绘效果
    MATLAB——nctoolbox安装及使用
    Python——NumPy库入门
    Failed to connect to github.com port 443: Timed out
    python 调用C++ DLL,传递int,char,char*,数组和多维数组
    python基础
    linux常用命令
  • 原文地址:https://www.cnblogs.com/ZefengYao/p/7783302.html
Copyright © 2020-2023  润新知