查找给定对的解决方案(因子数量,主要因子数量)
问题内容:
我一直在考虑x
和k
,这里x
是许多因素的数量A
,并且k
是素因子的数量A
。给定x
和k
,我必须找出是否A
存在这种情况。
例如:
INPUT : 4 2
OUTPUT : 1
由于6是具有4个因数1、2、3、6的数,其中2是质数(2,3)。还给出了,x
并且k
可以具有1到10 9之间的任何值。
这是我的代码:
long long int x, k;
scanf("%lld%lld", &x, &k);
int ans = 0;
bool stop = false;
for (long long int numbers = 1; numbers < pow(10, 9) && !stop; numbers++) {
long long int noOfFactors = 0, noOfPrimes = 0;
for (long long int a = 1; a <= numbers && !stop; a++) {
if (numbers % a == 0) {
noOfFactors += 1;
if ((isprime(a)) == 1) {
noOfPrimes += 1;
}
}
}
if (noOfFactors == x && noOfPrimes == k) {
ans = 1;
stop = true;
} else
ans = 0;
}
printf("%d\n", ans);
当isprime(x)
返回1,如果x是首要否则为0。
但是在运行程序时,它显示TLE错误。谁能帮助我优化该算法,或者如果存在其他方法,您可以向我解释一下吗?在优化此算法或使用其他方法方面的任何帮助将不胜感激。
问题答案:
令 p 1, p 2, p 3,… p k 为某个正整数 n
的素因子。由算术基本定理,
Ñ 可以被表示为 p 1 ë 1 • p 2 ë 2 • p 3 é 3 •… p ķ Ë ķ 一些正整数
ë 1, ë 2, ë 3,… Ë ķ 。此外,这种正整数的任何这样的集合以这种方式表示一个正整数。
的各因素 Ñ 可以被表示为 p 1 ˚F 1 • p 2 ˚F 2 • p 3 ˚F 3 •… p ķ ˚F
ķ 对于某些整数 ˚F 我 其中0≤ ˚F 我 ≤ ë 我 。
每个 f i 可以具有从0到 e i的 e i +1值,因此 n 的因数为( e 1 +1)•( e 2 +1)•(
e 3 +1)•…( e k + 1)。
由于每个 e i 必须为正,因此每个 e i +1必须至少为2。现在我们可以看到,如果 n 具有 x个 因数,则 x 可表示为
k个 整数的乘积,每个整数至少为2。反之,如果 x 可以表示为 k个 整数的乘积,每个整数至少为2,该乘积为我们提供 e i的
值,这为我们提供了一个具有 x个 因子和 k个 素数因子的正整数 n 。
因此,当且仅当 x 可表示为 k个 整数的乘积,且每个整数至少为2时,存在具有 x个 因子和 k个 素数的数字。
要对此进行测试,只需将 x 除以质数即可, 例如 ,将除以2,然后除以3,再除以5,以此类推。一旦将 x 除以 k
-1个因子并且结果大于1,则我们知道 x 可表示为 k个 整数的乘积,每个整数至少为2(最后一个可以是合成的,而不是质数,例如2•3
•3•3•35)。如果 x 在我们除以 k -1个因子之前或正好达到1时,则不存在这样的数字。
附录
进一步考虑,在对因子进行 x 检验时,不必使用质数作为候选。我们可以简单地遍历整数,测试每个候选 f 是否是 x 的因数。尝试通过首先测试
f 是否为素数来过滤它们,比简单测试 f 是否为 x 的因子要花费更多的时间。(这并不是说测试 x
的素数因子的更复杂的方法,例如使用准备好的包含许多素数的表,不会更快。)因此,下面的代码就足够了。
#include <stdint.h>
/* Return true if and only if there exists a positive integer A with exactly
x factors and exactly k prime factors.
*/
static _Bool DoesAExist(uintmax_t x, uintmax_t k)
{
/* The only positive integer with no prime factors is 1. 1 has exactly
one factor. So, if A must have no prime factors (k is zero), then an A
exists if and only if x is one.
*/
if (k == 0) return x == 1;
/* A number with exactly one prime factor (say p) has at least two factors
(1 and p) and can have any greater number of factors (p^2, p^3,...).
So, if k is one, then an A exists if and only if x is greater than one.
*/
if (k == 1) return 1 < x;
/* Otherwise, an A exists only if x can be expressed as the product of
exactly k factors greater than 1. Test this by dividing x by factors
greater than 1 until either we have divided by k-1 factors (so one
more is needed) or we run out of possible factors.
We start testing factors with two (f = 2).
If we find k factors of x during the loop, we return true.
Otherwise, we continue as long as there might be more factors. (When
f*f <= x is false, we have tested the current value of x by every
integer from two to the square root of x. Then x cannot have any more
factors less than x, because if there is any factorization x = r*s,
either r or s must be less than or equal to the square root of x.)
For each f, as long as it is a factor of the current value of x and we
need more factors, we divide x by it and decrement k to track the
number of factors still required.
*/
for (uintmax_t f = 2; f*f <= x; ++f)
while (x % f == 0)
{
/* As long as f is a factor of x, remove it from x and decrement
the count of factors still needed. If that number reaches one,
then:
If the current value of x exceeds one, it serves as the
last factor, and an A exists, so we return true.
If the current value of x exceeds one, there is no
additional factor, but we still need one, so no A exists,
so we return false.
*/
x /= f;
if (--k <= 1) return 1 < x;
}
/* At this point, we need k more factors for x, and k is greater than one
but x is one or prime, so x does not have enough factors. So no A with
the required properties exists, and we return false.
*/
return 0;
}
#include <stdio.h>
int main(void)
{
printf("False test cases:\n");
printf("%d\n", DoesAExist(0, 0)); // False since each positive integer has at least one factor (1).
printf("%d\n", DoesAExist(2, 0)); // False since no number has two factors and no prime factors.
printf("%d\n", DoesAExist(0, 1)); // False since each positive integer has at least one factor (1).
printf("%d\n", DoesAExist(1, 1)); // False since each positive integer with a prime factor has at least two factors (one and the prime).
printf("%d\n", DoesAExist(2, 2)); // False since each number with two prime factors (p and q) has at least four factors (1, p, q, and pq).
printf("%d\n", DoesAExist(3, 2)); // False since each number with two prime factors (p and q) has at least four factors (1, p, q, and pq).
printf("%d\n", DoesAExist(8, 4));
printf("%d\n", DoesAExist(6, 3));
printf("%d\n", DoesAExist(22, 3));
printf("%d\n", DoesAExist(24, 5));
printf("%d\n", DoesAExist(88, 5));
printf("%d\n", DoesAExist(18, 4));
printf("%d\n", DoesAExist(54, 5));
printf("%d\n", DoesAExist(242, 4));
printf("%d\n", DoesAExist(2662, 5));
printf("True test cases:\n");
printf("%d\n", DoesAExist(1, 0)); // True since 1 has one factor and zero prime factors.
printf("%d\n", DoesAExist(2, 1)); // True since each prime has two factors.
printf("%d\n", DoesAExist(3, 1)); // True since each square of a prime has three factors.
printf("%d\n", DoesAExist(4, 1)); // True since each cube of a prime has three factors.
printf("%d\n", DoesAExist(4, 2)); // True since each number that is the product of two primes (p and q) has four factors (1, p, q, and pq).
printf("%d\n", DoesAExist(8, 2));
printf("%d\n", DoesAExist(8, 3));
printf("%d\n", DoesAExist(6, 2));
printf("%d\n", DoesAExist(22, 2));
printf("%d\n", DoesAExist(24, 2));
printf("%d\n", DoesAExist(24, 3));
printf("%d\n", DoesAExist(24, 4));
printf("%d\n", DoesAExist(88, 2));
printf("%d\n", DoesAExist(88, 3));
printf("%d\n", DoesAExist(88, 4));
printf("%d\n", DoesAExist(18, 2));
printf("%d\n", DoesAExist(18, 3));
printf("%d\n", DoesAExist(54, 2));
printf("%d\n", DoesAExist(54, 3));
printf("%d\n", DoesAExist(54, 4));
printf("%d\n", DoesAExist(242, 2));
printf("%d\n", DoesAExist(242, 3));
printf("%d\n", DoesAExist(2662, 2));
printf("%d\n", DoesAExist(2662, 3));
printf("%d\n", DoesAExist(2662, 4));
}