POJ 1150 (数论)

原创 2018年04月16日 22:52:20

题意,求n!/(n-m)!末尾第一个非零的数是什么。

思路:这题折腾了我一晚上,终于搞明白了。以10!为例,首先,要去除末尾的0,要把因子10去除,但10不是质数,所以就考虑2*5;去除所有的2,5;例如:1 2 3 4 5 6 7 8 9 10,去除了因子2和5之后,就变为了1 1 3 1 1 1 7 1 9 1;

那么这就相当于一个子问题了,我们可以用递归来求解。

这样,整个序列就只剩下1 3 7 9 这四个数了,我们现在要找的就是序列中数字末尾为3 7 9的个数。这个是本题的重点

我们可以把这个序列分为奇偶,1 3 5 7 9, 和 2 4 6 8 10;

我们尝试统计,可以发现奇数和偶数中3 7 9的个数是一样的。因此,我们依然可以递归求解

f(n) = f(n/2)+g(n)   g(n)为奇数序列中的数目。

我们继续观察奇数的序列 1 3 5 7 9 11 13 15 17 19 21 23 25;

其中5 15 25 是5的奇数倍,那么我们要统计序列中 3 7 9 的个数g(n,x) = n/10 + (n%10>=x) + g(n/5,x);

最后就是把所有这些数相乘。同过观察,2 3 7 9这四个数都是周期为4。这样就能方便的求解了。

还有就是判断一下5和2的个数:

如果num5>num2,直接输出5就行了。

如果num5<=num2,如果不相等的话就要把多出来的2先处理掉,再继续想3 7 9;

最后上代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>

using namespace std;
typedef long long ll;

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 g(int n,int x)
{
    if(n==0)
        return 0;
    return n/10+(n%10>=x)+g(n/5,x);//1-n末尾为x的个数
}

int getx(int n,int x)
{
    if(n==0)
        return 0;
    return getx(n/2,x)+g(n,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()
{
    int n,m;
    while(cin >> n >> m)
    {
        int num2 = get2(n)-get2(n-m);
        int num5 = get5(n)-get5(n-m);
        int num3 = getx(n,3)-getx(n-m,3);
        int num7 = getx(n,7)-getx(n-m,7);
        int num9 = getx(n,9)-getx(n-m,9);
        int res = 1;
        if(num5>num2)
        {
            cout<<"5"<<endl;
            continue;
        }
        else
        {
            if(num5!=num2)
            {
                res *= table[0][(num2-num5)%4];
                res %= 10;
            }
            res *= table[1][num3%4];
            res %= 10;
            res *= table[2][num7%4];
            res %= 10;
            res *= table[3][num9%4];
            res %= 10;
            cout<<res<<endl;
        }
    }
    return 0;
}


精通memcached数据库管理深度讲解

-
  • 1970年01月01日 08:00

POJ【数论/组合/博弈论】

POJ【数论/组合/博弈论】题目列表 POJ【数论/组合/博弈论】题目列表 原来的列表比较水,今天换了一个难一些的列表,重新开始做~ 红色的代表已经AC过,蓝色的代表做了但是还没过。这句话貌似在我空...
  • u013986860
  • u013986860
  • 2014-05-20 16:53:49
  • 1443

POJ 新手题目+部分难题 基本数论+图论+组合数学

  • 2009年12月14日 14:40
  • 6.09MB
  • 下载

poj1150

题意: 计算A(n,m)的最后一位非0的数。 分析引用下面文章。出处:http://duanple.blog.163.com/blog/static/7097176...
  • ocgcn2010
  • ocgcn2010
  • 2015-01-21 17:08:53
  • 350

POJ 1150 The Last Non-zero Digit 阶乘最后非0位

转自:http://www.cppblog.com/abilitytao/archive/2009/10/31/99907.html 这个题怎么来做呢?先别急,我们先来讨论一下下面几个子问题: ...
  • Tsaid
  • Tsaid
  • 2012-02-16 20:11:11
  • 1737

poj 1150 数论

排列数的最后一个非零数字 一个做了好久的题目     2*5会产生0,其余的因子都不能     所以把所有的因子2 5提取出来,然后统计剩下的37 9的个数,自己计算循环节及可得出答案。...
  • yrleep
  • yrleep
  • 2013-04-14 19:41:07
  • 524

POJ Sumdiv (数论+二分等比数列求和)

【题目链接】:click here~~ 【题目大意】求 其中sum()表示其所有因子和(0= 【思路】 二分等比数列求和,我们先把A的质因子分解出来,然后如下(poj讨论区的思路~~) 1+p+...
  • u013050857
  • u013050857
  • 2015-09-22 17:11:51
  • 1163

POJ2909&&POJ1730基础数论

Goldbach's Conjecture Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9...
  • u011481752
  • u011481752
  • 2014-07-11 15:39:51
  • 594

POJ 1019 数论基础题

Number Sequence Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 37350 ...
  • Turne
  • Turne
  • 2016-03-31 19:16:16
  • 466

POJ2773 Happy 2006【容斥原理】

题目大意: 给你两个整数N和K,找到第k个与N互素的数(互素的数从小到大排列),其中 (1 ...
  • u011676797
  • u011676797
  • 2015-08-12 17:55:51
  • 621
收藏助手
不良信息举报
您举报文章:POJ 1150 (数论)
举报原因:
原因补充:

(最多只允许输入30个字)