JOJ1926:Factovisors

传送门:http://acm.jlu.edu.cn/joj/showproblem.php?pid=1926

题意:求解m是否可以整除n!。

思路:先把素数筛选出来,因为n和m都是2^31 - 1的范围,所以50000应该足够了。

之后将m分解质数,得到质数数组和其个数,用所得的素数数组对n!里面寻找相质数的个数,看是否大于m中的个数。

代码:

#include <cstdio>
#include <memory.h>

int main()
{
    int a[5000], num[5000], prime[47000], n, m, i, j, cnt, temp, sum;
    bool flag;
    memset(prime, 0, sizeof(prime));
    for (i = 1; i < 47000; i += 2)
        prime[i] = 1;
    prime[2] = 1;
    for (i = 3; i < 217; i += 2)
        for (j = i * i; j < 47000; j += 2 * i)
            prime[j] = 0;
    while (scanf("%d%d", &n, &m) != EOF)
    {
        if (m == 0)
            flag = false;
        else
        if (n >= m)
            flag = true;
        else
        {
            flag = true, cnt = 0, temp = m;
            memset(num, 0, sizeof(num));
            for (i = 2; i < 47000; ++i)
            {
                if (prime[i] == 0)
                    continue;
                if (temp % i == 0)
                {
                    a[cnt] = i;
                    while (temp % i == 0)
                    {
                        num[cnt]++;
                        temp /= i;
                    }
                    cnt++;
                }
                if (temp == 1) break;
            }
            if (temp >= 47000)
            {
                a[cnt] = temp;
                num[cnt++]++;
            }
            for (i = cnt - 1; i >= 0; --i)
            {
                if (a[i] > n)
                {
                    flag = false;
                    break;
                }
                sum = 0, temp = n;
                while (temp)
                {
                    sum += temp / a[i];
                    temp /= a[i];
                }
                if (sum < num[i])
                {
                    flag = false;
                    break;
                }
            }
        }
        if (flag)
            printf("%d divides %d!\n", m, n);
        else
            printf("%d does not divide %d!\n", m, n);
    }
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值