剑指Offer - 九度1514 - 数值的整数次方
2013-11-30 00:49
- 题目描述:
-
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
- 输入:
-
输入可能包含多个测试样例。
对于每个输入文件,第一行输入一个整数T,表示测试案例的数目,接下来的T行每行输入一个浮点数base和一个整数exponent,两个数中间用一个空格隔开。
- 输出:
-
对应每个测试案例,
输出一个浮点数代表答案,保留两位小数即可。
- 样例输入:
-
5 1.0 10 0.0 -5 1.0 0 1.2 5 2.0 -1
- 样例输出:
-
1.00e+00f INF 1.00e+00f 2.49e+00f 5.00e-01f
题意分析:
coding面试题考察的不仅仅是算法数据结构,还注重考验面试者的仔细程度。因此有些人碰见一些看起来没什么算法难点的题就觉得很简单,比如“判断三条边能否构成三角形”之类的“简单题”。
这一题也是这样,求一个浮点数的整数次方。我们定义底数为double x,指数为int n。对于求结果的算法,我们可以用for循环在O(n)的时间得出结果;也可以用快速幂的思想,二分用O(log(n))的时间求解。毫无疑问我们应该选择后者(如果你要从数值的角度深究误差传递的问题,就可能没那么简单了(O_o)zzZ)。
算法想完了,接着就开始写吧。三两句写完后,开始yy测试用例,主要是各种边界值:
x的情况:
正数:正常case
负数:(-x)^n = (-1)^n * x^n
0:0的负数次方无意义,因为除0会造成浮点错误SIGFPE。
n的情况
正数:正常case
负数:x^(-n) = 1 / x^n
0:非零数的零次方都是1,0的0次方右极限为1,值不存在(我描点绘图验证过,但数学不好,不会证..见笑)。
所有组合情况都考虑到,然后将处理特殊case的代码加上,就能够通过检验了。
1 // 651842 zhuli19901106 1514 Accepted 点击此处查看所有case的执行结果 1020KB 795B 80MS 2 // 201311151751 3 #include <cstdio> 4 using namespace std; 5 6 double myexp(double x, int n) 7 { 8 if(n == 0){ 9 return 1; 10 }else if(n < 0){ 11 return myexp(1.0 / x, -n); 12 }else{ 13 if(x < 0){ 14 return (n % 2 ? -1 : 1) * myexp(-x, n); 15 } 16 double res = myexp(x, n / 2); 17 if(n % 2){ 18 return res * res * x; 19 }else{ 20 return res * res; 21 } 22 } 23 } 24 25 int main() 26 { 27 int t, ti; 28 double x, res; 29 int n; 30 31 while(scanf("%d", &t) == 1){ 32 for(ti = 0; ti < t; ++ti){ 33 scanf("%lf%d", &x, &n); 34 if(x == 0.0){ 35 if(n >= 0){ 36 printf("%.2ef\n", 0.0); 37 }else{ 38 printf("INF\n"); 39 } 40 }else{ 41 res = myexp(x, n); 42 printf("%.2ef\n", res); 43 } 44 } 45 } 46 47 return 0; 48 }