您的位置:首页 > 编程语言 > C#

P次方数-c#求解-英雄会在线编程题目

2014-02-25 13:36 295 查看
先看题目吧:

P次方数

发布公司:
有 效 期:
赛 区:

CSDN

2014-02-24至2014-03-26

北京

难 度 等 级:
答 题 时 长:
编程语言要求:











120分钟
C C++ Java C#

题目详情
一个整数N,|N| >= 2, 如果存在整数x,使得N = x * x * x... (p个x相乘) =x^p,则称N是p次方数,给定32位内的整数N,求最大的P。例如N=5,输出1,N=36则输出2。

这道题没有什么难以思考的地方,思路很简单,就是吧一个给定的数开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--;

}

}

这里最大的问题就是,n可能是一个非常大的质数,那循环次数太多,时间基本上就挂了,所以还是直接开方比较好
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: