POJ1001 Exponentiation
题目来源:http://poj.org/problem?id=1001
题目大意:给出一个0.0至99.999 之间的实数R和一个1至25之间的整数,求Rn。
输入:一组R和n,每行的第1行至第6列为R,第8列至第9列为n。
输出:每行表示一个Rn的实际值。
Sample Input
95.123 12 0.4321 20 5.1234 15 6.7592 9 98.999 10 1.0100 12
Sample Output
548815620517731830194541.899025343415715973535967221869852721 .00000005148554641076956121994511276767154838481760200726351203835429763013462401 43992025569.928573701266488041146654993318703707511666295476720493953024 29448126.764121021618164430206909037173276672 90429072743629540498.107596019456651774561044010001 1.126825030131969720661201
解题关键:
1. 所求得的结果很可能超出了C/C++等语言标准类型的表达范围,所以需要以字符串来保存结果。
2. 显然可以将指数运算用连乘来实现。
3. 用倒序保存中间结果比较方便,可以避免进位时产生移位的操作。
1 ////////////////////////////////////////////////////////////////////////// 2 // POJ1001 Exponentiation 3 // Memory: 284K Time: 0MS 4 // Language: C++ Result: Accepted 5 ////////////////////////////////////////////////////////////////////////// 6 7 #include <iostream> 8 9 using namespace std; 10 11 int result[130]; //保存结果 12 13 //将当前结果与底数相乘一次更新结果 14 void multiply(int multiplier) { 15 16 //辅助数组 17 int temp[130]; 18 for (int i = 0; i < 130; i++) { 19 temp[i] = 0; 20 } 21 22 for (int i = 0; i < 125; i++) { 23 int t = result[i] * multiplier; //第i位与乘数相乘 24 int carry = (t + temp[i]) / 10; //剩余数 25 temp[i] = (t + temp[i]) % 10; //计算第i位 26 27 //依次处理高位 28 int g = 1; 29 while (carry) { 30 int t = temp[i + g] + carry; 31 carry = t / 10; 32 temp[i + g] = t % 10; 33 g++; 34 } 35 } 36 for (int i = 0; i < 130; i++) { 37 result[i] = temp[i]; 38 } 39 } 40 41 //输出 42 void output(int sign) { 43 int start = 0; 44 int end = 129; 45 //寻找不为0的最高位 46 for (int i = 0; i <= sign && i <= 129; i++) { 47 start = i; 48 if (result[i] != 0) { 49 break; 50 } 51 } 52 53 //寻找不为0的最低位 54 for (int i = 129; i >= 0; i--) { 55 if (i == sign - 1) { 56 end = i; 57 break; 58 } 59 if (result[i] != 0) { 60 end = i; 61 break; 62 } 63 } 64 65 //依序输出各位 66 for (int i = end; i >= start; i--) { 67 if (i == sign - 1) { 68 cout << '.'; 69 } 70 cout << result[i]; 71 } 72 cout << endl; 73 } 74 75 int main(void) 76 { 77 char c; 78 79 while ((c = getchar()) != EOF) { 80 int multiplier = 0; //记录底数(以整数形式记,不考虑小数点) 81 int sign = 0; //记录小数点位置 82 int index = 4; 83 84 //结果所有位初始化为0 85 for (int i = 0; i < 130; i++) { 86 result[i] = 0; 87 } 88 89 //处理输入 90 for (int i = 1; i <= 5; i++) { 91 if (c == '.') { 92 //读入的位为小数点,记录小数点位数 93 sign = i; 94 } else { 95 //读入的位为数字,计算底数 96 multiplier = multiplier * 10 + (c - '0'); 97 //倒序保存至初始结果 98 result[index--] = int(c - '0'); 99 } 100 c = getchar(); 101 } 102 //处理最后一位 103 if (c == '.') { 104 sign = 6; 105 } else { 106 multiplier = multiplier * 10 + (c - '0'); 107 result[index--] = int(c - '0'); 108 } 109 //计算小数点后位数 110 sign = 6 - sign; 111 112 //n为指数 113 int n = 0; 114 cin >> n; 115 116 //连乘 117 for (int i = 1; i < n; i++) { 118 multiply(multiplier); 119 } 120 121 //计算小数点位置 122 sign = sign * n; 123 output(sign); 124 getchar(); //去回车符 125 } 126 system("pause"); 127 return 0; 128 }