传送门: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;
}