求高精度幂
Time Limit: 500MS | Memory Limit: 10000K | |
Total Submissions: 120823 | Accepted: 29507 |
Description
对数值很大、精度很高的数进行高精度计算是一类十分常见的问题。比如,对国债进行计算就是属于这类问题。
现在要你解决的问题是:对一个实数R( 0.0 < R < 99.999 ),要求写程序精确计算 R 的 n 次方(R n),其中n 是整数并且 0 < n <= 25。
现在要你解决的问题是:对一个实数R( 0.0 < R < 99.999 ),要求写程序精确计算 R 的 n 次方(R n),其中n 是整数并且 0 < n <= 25。
Input
T输入包括多组 R 和 n。 R 的值占第 1 到第 6 列,n 的值占第 8 和第 9 列。
Output
对于每组输入,要求输出一行,该行包含精确的 R 的 n 次方。输出需要去掉前导的 0 后不要的 0 。如果输出是整数,不要输出小数点。
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
这题对格式要求也太高了,稍微一个不小心,就报错,还有,命名要求是:一个实数R( 0.0 < R < 99.999 ),要求写程序精确计算 R 的 n 次方(Rn),其中n 是整数并且 0 < n <= 25。但是测试数据中却需要R=0和n=0的数据,不管怎么样,终于把这个问题解决了,多亏大神提供的变态测试数据,通过了这个变态数据的测试,终于accpted.
95.123 12 0.4321 20 5.1234 15 6.7592 9 98.999 10 1.0100 12 .00001 1 .12345 1 0001.1 1 1.1000 1 10.000 1 000.10 1 000000 1 000.00 1 .00000 0 000010 1 000.10 1 0000.1 1 00.111 1 0.0001 1 0.0001 3 0.0010 1 0.0010 3 0.0100 1 0.0100 3 0.1000 1 0.1000 3 1.0000 1 1.0000 3 1.0001 1 1.0001 3 1.0010 1 1.0010 3 1.0100 1 1.0100 3 1.1000 1 1.1000 3 10.000 1 10.000 3 10.001 1 10.001 3 10.010 1 10.010 3 10.100 1 10.100 3 99.000 1 99.000 3 99.001 1 99.001 3 99.010 1 99.010 3 99.100 1 99.100 3 99.998 1 99.998 3
现贴出代码,不敢说很好,只是如果不是针对这道题,里面的Add函数可用于整形大数相加,而Mul可用于一个整形大数与一个int型整数相乘,格式的输入输出控制都在主函数处理:
#include <iostream> #include <string> #include <cmath> #include <sstream> #include <vector> #include <fstream> using namespace std; string Add(string s1,string s2) //两个整数大数相加,以字符串的形式 { int len1=s1.size(); int len2=s2.size(); string maxStr; string minStr; int minLen; int maxLen; if (len1<=len2) { maxStr=s2; minStr=s1; minLen=len1; maxLen=len2; } else { maxStr=s1; minStr=s2; minLen=len2; maxLen=len1; } string str(maxLen+1,'0'); int i,j,temp; for(i=minLen-1,j=maxLen-1;i>=0;i--,j--) { temp=(minStr[i]-'0')+(maxStr[j]-'0')+(str[j+1]-'0'); str[j+1]=temp%10+'0'; str[j]+=temp/10; } for (i=maxLen-minLen-1;i>=0;i--) { temp=(maxStr[i]-'0')+(str[i+1]-'0'); str[i]+=temp/10; str[i+1]=temp%10+'0'; } if(str[0]=='0') { return str.substr(1); } else return str; } string Mul(string s1,string s2) //一个整数大数与一个整数的乘积 { vector<string> vec; vec.clear(); long num=atoi(s1.c_str()); int k=0; for(int i=s2.size()-1;i>=0;i--) { long j=(s2[i]-48); long t=j*num; string c; ostringstream oss; oss<<t; c=oss.str(); c.append(k,'0'); vec.push_back(c); k++; } string s; if (vec.size()>=2) { s=Add(vec[0],vec[1]); for(k=2;k<vec.size();k++) s=Add(s,vec[k]); } else s=vec[0]; return s; } string StringPow(string s,int n) //一个整数大数的n次幂 { string str=s; while(--n) { str=Mul(s,str); } return str; } int main() { string s; int n; //ifstream fin("e:\\data.txt"); //while (fin>>s>>n) while (cin>>s>>n) { string str; int count=0; for (int i=0;i<s.size();i++) { if (s[i]=='0'||s[i]=='.') { count++; } } if (count==s.size()) { str="0"; //对于输入的s形如 000000,0.0000,.00000等形式的处理 } else //输入的s是正数 { int pos=s.find('.'); int num; if (pos!=s.npos) //输入的s是小数 { int exp=s.size()-(pos+1); s.erase(pos,1); //去除小数点,比如1.01变为101(小数变整数) int num=exp*n; //最后结果移动的小数点位(比如1.01的立方=101*101*101向左移动2*3位(此时n=3,num=3) int i; for (i=0;i<s.size();i++) { if (s[i]!='0') { s=s.substr(i); //去除整型大数前面的0,比如0101变为101 break; } } str=StringPow(s,n); //str保存s的n次幂值 int p=str.size()-num; if (p<0) //处理一种特殊情况,向左进的位大于结果的位数 { str.insert((size_t)0,-p,'0'); str.insert((size_t)0,1,'.'); } else str.insert(p,1,'.'); //移动小数点位,得到正确的结果 } else //输入的s是整数 { for (i=0;i<s.size();i++) if (s[i]!='0') { s=s.substr(i); //去除整型大数前面的0,比如0101变为101 } str=StringPow(s,n); } pos=str.find('.'); if (pos!=s.npos) { for (i=str.size()-1;i>=pos;i--) { if (str[i]=='0') { str.erase((size_t)i,1); //去除小数点后面表示精度的0,比如1.2000变为1.2 } else break; } } int len=str.size(); if (str[len-1]=='.') { str.erase((size_t)(len-1),1); //处理一种特殊情况,比如10.变为10 } } cout<<str<<endl; } return 0; }