先看题目吧:
这道题没有什么难以思考的地方,思路很简单,就是吧一个给定的数开p次方。因为给定的数是32位以内的,所以,遍历一遍2~32就可以了。看看得到的数是不是一个整数,是的话,就说明可以开p次方,可以从高向低尝试,我第一次写是从低向高尝试的。
这里需要注意一点,就是开p次方运算,得到的并非一定是一个整数,可能是一个非常接近整数的值,比如:4.999999872之类的,或者5.000000023这样的,所以我们需要先四舍五入,然后判断差值,当差值小于一定值的时候,我们可以认为,这个n可以正好开p次方。
有了这个思路,代码就很简单了。
注意的第二点:因为有可能是负数,所以,负数只能是开奇数次方。
注意第三点:因为是32位,所以考虑边界问题,用long来存储。
下面看代码:
public static int cal(int x)
{
long n = (long)x;
int count = 1;
int num=0;
double r = 1.0 /(double) (1 << 20);
if (n > 0)
{
for (int i = 2; i <= 32; i++)
{
double t = 1.0 / (double)i;
double d = Math.Pow(n, t);
num = (int)(d + 0.5);
if (d < 2)
{
break;
}
if (Math.Abs(num - d) <= r)
{
count = i;
}
}
}
else
{
n = n * -1;
for(int i=3;i<32;i=i+2)
{
double t = 1.0 / (double)i;
double d = Math.Pow(n, t);
num = (int)(d + 0.5);
if (Math.Abs(d) < 2)
{
break;
}
if (Math.Abs(num - d) <= r)
{
count = i;
}
}
}
return count;
}
当然还有另外一种思路:
就是先把n分成若干个质数的乘积,这里需要汇总相同质数的个数,然后求各个质数个数的最大公约数。
如果只有一个质数,直接返回个数。
如果是多个质数,返回最大公约数。
比如说:8=2*2*2,质数2有3个,直接返回3.
比如说:2*2*2*3*3*3,质数2有3个,质数3有3个,返回3,3的最大公约数:3
返回几个数的最大公约数很简单,问题就是,返回一个给定的数,是由哪些数相乘得到的,必然会遍历2~sqrt(n)的所有数,当然也可以一边遍历一边降低n。
for (int i = 2; i<= n; i++)
{
if (n % i == 0)
{
if (dic.ContainsKey(i))
{
dic[i]++;
}
else
{
dic.Add(i, 1);
}
n = n / i;
i--;
}
}
原文:http://blog.csdn.net/mamihong/article/details/19908841