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

来源:互联网 发布:laura名字的含义 知乎 编辑:程序博客网 时间:2024/03/29 18:30

       先看题目吧:

P次方数
  • 发布公司:
  • 有 效 期:
  • 赛    区:
  • CSDN
  • 2014-02-242014-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可能是一个非常大的质数,那循环次数太多,时间基本上就挂了,所以还是直接开方比较好
0 0