Problem: Given a positive integer n, find if it can be expressed as x^y where y > 1 and x > 0 and x, y both are both integers.
For example:
n = x^y
taking log both sides
log(n) = y*log(x)
y = log(n) / log(x)
Hence, we have to find an integer x for which RHS gives an integer y.
Algorithm:
For example:
- N = 125 As 125 can be written as x^y where x = 5, y = 3, so return true.
- N = 120 As no two integers exist for which we can write 120 = x^y, return false.
#include <bits/stdc++.h>
using namespace std;
/* Returns true if n can be written as x^y */
bool isOk(int n)
{
if (n==1)
return true;
/* Try all numbers from 2 to sqrt(n) */
for (int x = 2; x <= sqrt(n); x++)
{
int y = 2, p = pow(x, y);
/* Keep increasing y while power 'p' is smaller
than n */
while (p <= n && p > 0)
{
if (p == n)
return true;
y++;
p = pow(x, y);
}
}
return false;
}
int main()
{
int n;
n = 125;
cout<<isOk(n)<<"\n";
n = 120;
cout<<isOk(n)<<"\n";
return 0;
}
Output:
1 0One optimization is to avoid calling pow() function by multiplying p with x one by one.
#include <bits/stdc++.h>
using namespace std;
bool isOk(int n)
{
for (int i = 2; i <= sqrt(n); i++)
{
int p = i;
while(p<=n)
{
p*=i;
if(p==n)
return true;
}
}
return false;
}
int main()
{
int n;
n = 125;
cout<<isOk(n)<<"\n";
n = 120;
cout<<isOk(n)<<"\n";
return 0;
}
Output:
1 0Instead of repeated multiplication, we can apply mathematical formula.
n = x^y
taking log both sides
log(n) = y*log(x)
y = log(n) / log(x)
Hence, we have to find an integer x for which RHS gives an integer y.
Algorithm:
- Starting with i = 2, if (log a / log i) is an integer then return true.
- Else increment i by 1 till i < √a.
- If no such i is found, return false.
#include <bits/stdc++.h>
using namespace std;
/* function returns true if a number can be represented
as x^y else return false */
bool isOk(int n)
{
if(n==1)
return true;
/* we need to increment i upto sqrt(n) */
for (int i = 2; i <= sqrt(n); i++)
{
double val = log(n) / log(i);
if((val - (int)val) < 0.000000001)
{
return true;
}
}
return false;
}
/* Driver function */
int main()
{
int n;
n = 125;
cout<<isOk(n)<<"\n";
n = 120;
cout<<isOk(n)<<"\n";
return 0;
}
Output:
1 0