UVA 10139 Factovisors(数论)

Factovisors

The factorial function, n! is defined thus for n a non-negative integer:

   0! = 1
   n! = n * (n-1)!   (n > 0)

We say that a divides b if there exists an integer k such that

   k*a = b

The input to your program consists of several lines, each containing two non-negative integers, n and m, both less than 2^31. For each input line, output a line stating whether or not m divides n!, in the format shown below.

Sample Input

6 9
6 27
20 10000
20 100000
1000 1009

Output for Sample Input

9 divides 6!
27 does not divide 6!
10000 divides 20!
100000 does not divide 20!
1009 does not divide 1000!

题意:给出n和m,问m能否整除n的阶乘。

分析:可以对m进行质因数分解,得到每个素因子的个数,与n!中此因子的个数进行比较,若大于n!中此因子的个数,则不能整除。

#include<stdio.h>
#include<string.h>
#include<math.h>
const int MAXN = 100005;
int vis[MAXN], prime[10000], num;

void get_prime() //筛法求素数
{
    num = 0;
    memset(vis, 0, sizeof(vis));
    for(int i = 2; i < MAXN; i++)
    {
        if(!vis[i])
        {
            prime[num++] = i;
            for(int j = i + i; j < MAXN; j += i)
                vis[j] = 1;
        }
    }
}

int Cal(int w, int p) //计算w的阶乘中有多少个p
{
    int ans = 0;
    while(w)
    {
        w /= p;
        ans += w;
    }
    return ans;
}

bool judge(int n, int m)
{
	int k = (int)sqrt(m+0.5);
    for(int i = 0; i < num && prime[i] <= k; i++)
    {
        if(m % prime[i] == 0)
        {
            int cnt = 0;
            while(m % prime[i] == 0)
            {
                cnt++;
                m /= prime[i];
            }
            if(Cal(n, prime[i]) < cnt) return false;
        }
    } //此时若 m!=1,则m必为素数,如果n>=m,则m必定可以整除n!
    if(m > 1 && n < m) return false;
    return true;
}

int main()
{
    int n, m;
    get_prime();
    while(~scanf("%d%d",&n,&m))
    {
        if(judge(n, m)) printf("%d divides %d!\n", m, n);
        else printf("%d does not divide %d!\n", m, n);
    }
    return 0;
}

UVA 10139 Factovisors(数论),布布扣,bubuko.com

时间: 2024-10-09 18:52:39

UVA 10139 Factovisors(数论)的相关文章

UVa 10139 - Factovisors

题目:判断n!能否整除m. 分析:数论.先将m拆成素数的积的形式,再判断n!中对应每个素数的个数,是否大于m的即可. 首先,打表计算50000内素数,用这些素数除不尽的数一定也是素数,不过最多只有一个: 然后,分解m成素数的积的形式,统计每个素数因子的个数: 最后,判断n!中每个素数因子的个数是否大于m中对应的素数个数: 设f(n,p)为n!中素数p的个数,则有f(n,p)= f(n/p,p)+ n/p: { 能被p整除的数为:p,2p,3p,..,p^2,p(p+1),..,p^3,..,p^

uva 10127 - Ones(数论)

题目链接:uva 10127 - Ones 题目大意:给出n,问说者少要多少为1才可以整除n. 解题思路:等于是高精度取模,直到余数为0为止. #include <cstdio> #include <cstring> int main () { int n; while (scanf("%d", &n) == 1) { int ans = 1, c = 1; while (c) { c = (c * 10 + 1) % n; ans++; } print

UVA 10090 - Marbles (数论)

UVA 10090 - Marbles 题目链接 题意:有两种盒子,一种代价c1,能装n1个珠子,一种代价c2,能装n2个珠子,问如何正好装n个珠子,并且使得代价最少. 思路:利用扩展欧几里得算法求出n1?x+n2?y=n的一个解(x′,y′) 就可以知道x,y的通解分别为 x=x′?n/gcd(n1,n2)+n2/gcd(n1,n2)?t y=y′?n/gac(n1,n2)?n1/gcd(n1,n2)?t 由于x > 0 && y > 0,就可以求出t的范围. 那么t越小x越

UVA 1350 - Pinary(数论+递推)

题目链接:1350 - Pinary 题意:二进制数,不能有连续的1,给定第n个数字,输出相应的二进制数 思路:先是递推,求出由n位组成的数字中有几个满足条件 dp[i] = dp[i - 1] + dp[i - 2],考虑最后一位放0和倒1位放0的情况. 然后用一个sum[i]记录满足<=i位一共的情况 接着利用二分找到给定的n > sum[i - 1],i的最大值,这个就是所求的答案的最高位. 因为如果这位放1,那么就会一共多sum[i - 1] + 1个数,那么就还需要添加n - (su

uva 10844 - Bloques(数论+高精度)

题目链接:uva 10844 - Bloques 题目大意:给出一个n,表示有1~n这n个数,问有多少种划分子集的方法. 解题思路:递推+高精度. 1 1 2 2 3 5 5 7 10 15 15 20 27 37 52 dp[i][j]=dp[i?1][j?1]+dp[i][j?1] dp[i][0]=dp[i?1][i?1] ans[i]=dp[i][i] 需要用到高精度,并且缩进. #include <cstdio> #include <cstring> #include &

uva 1529 - Clock(数论)

题目链接:uva 1529 - Clock 题目大意:给出两个时间,问从第一个时间变成第二个时间分针会和时针重叠几次. 解题思路:两个针重叠的时间是固定的,只要处理出这些重叠的时刻,在判断说给得时间区间包含的个数即可. #include <cstdio> #include <cstring> #include <cmath> const int T = 12 * 60 * 100; const int D = 6545; int sh, sm, eh, em; int

UVA 756 - Biorhythms(数论)

756 - Biorhythms 题目链接 基本就是裸的中国剩余定理. 代码: #include <stdio.h> #include <string.h> const int M = 23 * 28 * 33; const int m[3] = {23, 28, 33}; int p[3], d; int gcd(int a, int b, int &x, int &y) { if (!b) {x = 1; y = 0; return a;} int d = gc

UVA 278 - Chess(数论)

题目链接:278 - Chess 题意:求出四种棋子最多放几个 思路:车能放行列的较小值,王隔着放,皇后根据八皇后问题可知,也是放行列最小值. 关键在于马,之前做过一题类似的,马分一行,两行,和两行以上考虑,一行就能全放,两行就隔一个田字格放,三行以上就每个马隔一个位置放. 代码: #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; int t, n, m; c

UVA 1434 - YAPTCHA(数论)

UVA 1434 - YAPTCHA 题目链接 题意:求出题目中那个公式的答案 思路: 当3?k+7非素数的时候,那么(3?k+6)!(由于必定能找到两个因子相乘) 所以原式为0 当3?k+7为素数的时候,依据威尔逊定理,((3?k+6)!+1)%(3?k+7)==0,因此原式能够转化为[x - (x - 1)] = 1 因此问题转化为仅仅要推断3 * k + 7是不是素数,那么就非常好办了,预处理出素数表,再预处理出答案就可以 代码: #include <stdio.h> #include