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 }
View Code
posted @ 2013-07-28 23:51  小菜刷题史  阅读(222)  评论(0编辑  收藏  举报