Reputation: 70
Currently the following problem is taking 3.008** seconds to execute for some testcase provided on hackerearth.com where allowed time is 3.0 seconds so i get time limit error. Please help to reduce execution time.
Problem: Alice has just learnt multiplying two integers. He wants to multiply two integers X and Y to form a number Z.To make the problem interesting he will choose X in the range [1,M] and Y in the range [1,N].Help him to find the number of ways in which he can do this.
Input
First line of the input is the number of test cases T. It is followed by T lines. Each line has three space separated integers, the numbers Z, M and N.
Output
For each test case output a single integer, the number of ways.
Constraints 1 <= T <= 50 1 <= Z <= 10^12 1 <= M <= 10^12 1 <= N <= 10^12
CODE:
#include <iostream>
using namespace std;
int chk_div(long long a,long long b)
{
if(((a/b) * (b) )==a)return 1;
return 0;
}
int main()
{
int t;
long i,j,count;
long n,m,z;
cin>>t;
while(t--)
{count=0;
cin>>z>>m>>n;
if(m>z)m=z;
if(n>z)n=z;
if (m>n)m=n;
for(i=1;i<=m;i++)
{
if(chk_div(z,i))count++;
}
cout<<count<<"\n";
}
return 0;
}
Upvotes: 2
Views: 3318
Reputation: 43078
I believe this should get the job done (idea from @zch's answer):
#include <iostream>
#include <cmath>
auto MAX = [] (int A, int B) -> bool { return A > B ? A : B; };
auto MIN = [] (int A, int B) -> bool { return A < B ? A : B; };
using std::cout;
using std::cin;
int main() {
long long Z, M, N, T, low, high, temp, div;
int ans;
for (cin >> T; T--; ) {
cin >> Z >> M >> N;
temp = MIN(M, N);
low = MIN(sqrt(Z), temp);
high = MAX(M, N);
for( ans = 0; low > 0 && (Z / low) <= high; --low ) {
if ( Z % low == 0) {
++ans;
div = Z / low;
ans += (div != low && div <= temp);
}
//cout << temp << " * " << Z / temp << " = " << Z << "\n";
}
cout << ans << "\n";
}
return 0;
}
Will be adding comments in a bit
Code with comments:
#include <iostream>
#include <cmath>
auto MAX = [] (int A, int B) -> bool { return A > B ? A : B; };
auto MIN = [] (int A, int B) -> bool { return A < B ? A : B; };
using std::cout;
using std::cin;
int main() {
long long Z, M, N, T, low, high, temp, div;
int ans;
for (cin >> T; T--; ) {
cin >> Z >> M >> N;
temp = MIN(M, N);
low = MIN(sqrt(Z), temp);//Lowest value <--We start iteration from this number
high = MAX(M, N); //Maximum value
for( ans = 0; low > 0 && (Z / low) <= high; --low ) {
//Number of things going on in this for-loop
//I will start by explaining the condition:
//We want to keep iterating until either low is below 1
// or when the expression (Z / low) > high.
//Notice that as the value of low approaches 0,
//the expression (Z / low) approaches inf
if ( Z % low == 0) {
//If this condition evaluates to true, we know 2 things:
/*Z is divisible by this value of low and
low is in the range of MIN(M,N) <--true*/
/*Because of our condition, (Z / low) is
within the range of MAX(M, N) <--true*/
++ans;
div = Z / low;
//This second part checks if the opposite is true i.e.
/*the value of low is in the range of
MAX(M, N) <--true*/
/*the value (Z / low) is in the range of
MIN(M, N) <--true only in some cases*/
ans += (div != low && div <= temp);
//(div != low) is to avoid double counting
/*An example of this is when Z, M, N have the values:
1000000, 1000000, 1000000
The value of low at the start is 1000 */
}
}
cout << ans << "\n";
}
return 0;
}
Upvotes: 5
Reputation: 217085
In fact, you have to resolve the problem in a different way:
find the Prime decomposition:
so Z = A^a * B^b * ... * P^p
with A, B, .., P
prime numbers
and so you just have to compute the number of possibilities from a, b, ... p
.
(So the result is up to (1 + a) * (1 + b) * ... * (1 + p)
depending of M&N constraints).
Upvotes: 2
Reputation: 1389
Upvotes: -1
Reputation: 15278
The main problem with performance here is the fact that your inner loop does about 10^12
iterations. You can reduce it a million times to sqrt(z) <= 10^6
.
The trick here is to notice that Alice can write z = x * y
if and only if he can write z = y * x
. Also, either x <= sqrt(z)
or y <= sqrt(z)
. Using these facts you can iterate only up to square root of z
to count all cases.
Upvotes: 8