时限:500 ms | 内存限制:10000 K | |
提交材料共计: 179923 | 接受: 43369 |
描述:求得数R( 0.0 < R < 99.999 )的n( 0 < n <= 25 )次方的精确值
样本输入
95.123 12 0.4321 20 5.1234 15 6.7592 9 98.999 10 1.0100 12
样本输出
548815620517731830194541.899025343415715973535967221869852721 .00000005148554641076956121994511276767154838481760200726351203835429763013462401 43992025569.928573701266488041146654993318703707511666295476720493953024 29448126.764121021618164430206909037173276672 90429072743629540498.107596019456651774561044010001 1.126825030131969720661201
分析:题中R的n次方远大于double的范围,那么就会想到用数组来存放结果,题目就变成了两个非常大的数相乘,小数相乘可以先把小数点去除,先算出小数点在结果中的位置,再直接计算两个整数相乘的值。
举例:95.123 12
求95.123的12次方的值,即先去除小数点,计算出小数点的位置(3 * 12 = 36), 再把95123相乘12次得出结果,输出时再插入小数点。
代码:
#include<iostream> #include<cstring> #include<string> using namespace std; const int N = 150; int result[N]; int temp[N]; int main() { string str; int n; while(cin >> str >> n) { for(int i = 0; i < N; i++) result[i] = 0; result[0] = 1; int m = 0; int cs[6] = {0}; int pos; for(int i = str.size() - 1; i >= 0; i--) { //去除小数点 if(str[i] != '.') cs[m++] = str[i] - '0'; else pos = i; } int point = (5 - pos)*n; for(int i = 0; i < n; i++) { for(int j = 0; j < N; j++) temp[j] = 0; for(int j = 0; j < 5; j++) { if(!cs[j]) continue; //如果乘数为0,那么无需向下执行 int c; for(int k = 0; k < N; k++) { //加到对应的位数上 c = result[k] * cs[j]; temp[k+j] += c; } for(int k = 0; k < N; k++) { //处理进位 if(temp[k] >= 10) { temp[k+1] += temp[k]/10; temp[k] %= 10; } } } for(int j = 0; j < N; j++) result[j] = temp[j]; //转存 } int l = 0; while(!result[l] && l < point) l++; int r = N - 1; while(!result[r] && r >= point) r--; for(int i = r; i >= point; i--) cout << result[i]; if(l < point) cout << "."; //如果的小数,那么输出小数点 for(int i = point - 1; i >= l; i--) cout << result[i]; cout << endl; } return 0; }
作者:kindleheart
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。