问题
I have been given x
and k
, where x
is the number of factors of a number A
, and k
is the number of prime factors of A
. Given x
and k
, I have to find out whether such an A
exists.
For example:
INPUT : 4 2
OUTPUT : 1
Since 6 is a number that has 4 factors 1, 2, 3, 6 out of which 2 are prime(2, 3).
Also it is given that x
and k
can have any values between 1 and 109.
Here is my code for the this:
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);
Where isprime(x)
returns 1 if x is prime else 0.
But while running the program, it shows TLE error. Can anyone help me out in optimising this algorithm, or if any other method exists, can you just explain it to me ? Any help in optimising this algorithm or using another method would be kindly appreciated.
回答1:
Let p1, p2, p3, … pk be the prime factors of some positive integer n. By the fundamental theorem of arithmetic, n can be represented as p1e1•p2e2•p3e3• … pkek for some positive integers e1, e2, e3, … ek. Furthermore, any such set of such positive integers represents one positive integer in this way.
Every factor of n can be represented as p1f1•p2f2•p3f3• … pkfk for some integers fi where 0 ≤ fi ≤ ei.
Each fi can have ei+1 values from 0 to ei, so the number of factors of n is (e1+1)•(e2+1)•(e3+1)• … (ek+1).
Since each ei must be positive, each ei+1 must be at least 2. Now we can see that, if n has x factors, then x is expressible as a product of k integers each at least 2. Conversely, if x is expressible as a product of k integers each at least 2, that product gives us values for ei, which gives us a positive integer n that has x factors and k prime factors.
Therefore, a number with x factors and k prime factors exists if and only if x is expressible as a product of k integers each at least 2.
To test this, simply divide x by prime numbers, e.g., divide by 2 as many times as possible without a remainder, then by 3, then by 5, and so on. Once x has been divided by k−1 factors and the result is greater than 1, then we know x is expressible as a product of k integers each at least 2 (the last may be composite rather than a prime, such as 2•3•3•3•35). If x reaches 1 before or just as we have divided it by k−1 factors, then no such number exists.
回答2:
So let me summarize my comments of above to answer the question 'how can I make it more efficient?'
- Store the
pow(10, 9)
in a variable, so you don't have to recalculate it every time a for-loop will do it's next iteration. - You can reduce the checking of
primeNum
to only 0 to its square, which makes sense, but if you don't feel comfortable, check out this question or wikipedia - If you checked that a number isn't prime, make sure you won't recalculate that again in the execution of the program, because checking for prime, especially when a number is very big, is time-consuming.
I think that's the most you can do about calculating with brute-force on primes, since there hasn't been found a faster way yet to check on prime.
回答3:
First your implementation is too inefficient
Don't call a function inside the for loop like this
for (long long int numbers = 1; numbers < pow(10, 9) && !stop; numbers++)
pow
will be called unnecessarily on each iteration. Save every constant to a variable before the loop. But in this case just usenumbers < 1e9
To get all factors of
n
you just need to loop untilsqrt(n)
. You're doingfor (long long int a = 1; a <= numbers && !stop; a++) { if (numbers % a == 0) {
so for example instead of only 104 loops for 108 you'll need 108 loops. Ifnumbers % a == 0
then botha
andnumbers/a
are factors ofnumbers
But the real issue here is that your algorithm is flawed. You can get all factors of A
if you know the prime factors of A
and their exponents. If A = p1m p2n ... pkp then A will have the following factors:
- p1i for i = 1..m
- p2i for i = 1..n
- ...
- pki for i = 1..p
- Factors from 2 prime factors: p1ip2j, p1ip3j,... p1ipkj, p2ip3j, p2ip4j,... p2ipkj,... pk-1ipkj
- Factors from 3 prime factors...
- Factors from k prime factors
This is purely a combination counting issue that can be done easily without even knowing A. Notice that the number of factors from k prime factors has some relation to the number of factors from k-1 prime factors
回答4:
Your algorithm is very inefficient. Here are a few ideas:
- reject obvious fails: if
x < 2
ork <= 0
orx < k
the answer is0
without further testing. - do not mix floating point and integer arithmetics. Use
1000000000
instead ofpow(10, 9)
. - the inner loop can be stopped much earlier than you do: only run it while
a * a < numbers
and add 2 divisors for each match. Add another divisor ifa * a == numbers
. - also stop the inner loop if
noOfFactors > x
ornoOfPrimes > k
.
The program will run faster, but still not fast enough, especially for large x
and k
. Solving this problem efficiently requires a mathematical approach: it does not depend which prime factors are involved in the factorisation to prove whether there are solutions. Here are a few hints for a more advanced analysis:
- you know how many prime factors
A
has, the only unknowns are the powers of these prime factors inA
. - you can compute the minimum number of factors for any given set of prime factors. This number is the total number of draws from the set, which is simply 2k. If
n
is less than this number for the givenk
, the answer is 0. - compute this number for small values of
k
, you will see that it grows very quickly, so the number of values ofk
to study is quite low. If thek
given is larger, the answer is 0. In practice fork = 30
there are at least 230 factors (1073741824). So ifk >= 30
the answer is no. - for the
k
given, compute the number of combinations for a given set of powers of the prime factors (a,b,c...) is(a+1)*(b+1)*(c+1)...
. You can use recursion to enumerate the powers such thata >= b >= c ...
stop the recursion as soon as the result exceedsn
. If you find a result equal ton
, the answer is 1. This analysis should complete very quickly.
来源:https://stackoverflow.com/questions/61054171/time-limit-excedeed-error-for-large-values