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可能是一个非常大的质数,那循环次数太多,时间基本上就挂了,所以还是直接开方比较好
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可能是一个非常大的质数,那循环次数太多,时间基本上就挂了,所以还是直接开方比较好
相关文章推荐
- C# 文本框只能输入数字
- C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 树形选择项目的标准例子
- C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 主细表事务处理的标准例子
- c#数字图像处理的3种方法示例分享
- C#删除程序自身【总结】
- SmartWeatherAPI_Lite_WebAPI C# 获取key加密
- [转载]c# winform 获取当前程序运行根目录
- c#字符串使用正则表达式示例
- c# 遇到的问题,求解?
- 动态执行c# 脚本片段
- C#读取EXCEL转化为DataSet
- chm帮助文档制作及C#调用
- (转)C#静态构造函数
- C#数字图像处理的3种方法
- C# 元数据学习
- C# CRC16 查表法
- c#控制台判断闰年
- C#语法糖,让编程更具乐趣
- C#操作注册表--DarrenF
- C#实现DirectShow技术开发准备