OJ_1001
来源:互联网 发布:画蜡烛图 软件 编辑:程序博客网 时间:2024/05/16 19:52
原题连接:http://poj.org/problem?id=1001&lang=zh-CN
求高精度幂
Time Limit: 500MS Memory Limit: 10000KTotal Submissions: 106968 Accepted: 26029
Description
对数值很大、精度很高的数进行高精度计算是一类十分常见的问题。比如,对国债进行计算就是属于这类问题。
现在要你解决的问题是:对一个实数R( 0.0 < R < 99.999 ),要求写程序精确计算 R 的 n 次方(Rn),其中n 是整数并且 0 < n <= 25。
现在要你解决的问题是:对一个实数R( 0.0 < R < 99.999 ),要求写程序精确计算 R 的 n 次方(Rn),其中n 是整数并且 0 < n <= 25。
Input
T输入包括多组 R 和 n。 R 的值占第 1 到第 6 列,n 的值占第 8 和第 9 列。
Output
对于每组输入,要求输出一行,该行包含精确的 R 的 n 次方。输出需要去掉前导的 0 后不要的 0 。如果输出是整数,不要输出小数点。
Sample Input
95.123 120.4321 205.1234 156.7592 998.999 101.0100 12
Sample Output
548815620517731830194541.899025343415715973535967221869852721.0000000514855464107695612199451127676715483848176020072635120383542976301346240143992025569.92857370126648804114665499331870370751166629547672049395302429448126.76412102161816443020690903717327667290429072743629540498.1075960194566517745610440100011.126825030131969720661201
Source
East Central North America 1988
Translator
北京大学程序设计实习,Xie Di
============================================================================
真TMD佩服CSDN,如此XX用户的意愿。自己上传的资源自己都不能删除,真是服大发了!如果代码
写的有问题难道还非得误导那些下载的朋友们!下面的代码已经放在新浪爱问资料共享,地址
http://iask.sina.com.cn/u/ish,没有上传工程文件,你可以随便用哪个版本的VC建一个就可以。
工程目录如下:
注:目前程序性能还达不到要求500MS,正在调试中。。。
/**************************************************************************************************///basecls.h/*运算实现的基类,不同的操作可以从此处派生出一个实现类*/#include <string>using namespace std;virtual class clsBaseAcl{public: virtual std::string Acl(const std::string strOp1, const std::string strOp2) = 0;}; /*************************************************************************************************///acl.h#include "basecls.h"class clsAdd:public clsBaseAcl{public: std::string Acl(const std::string strOp1, const std::string strOp2);};class clsSub:public clsBaseAcl{public: std::string Acl(const std::string strOp1, const std::string strOp2);};class clsMultiply:public clsBaseAcl{public: std::string Acl(const std::string strOp1, const std::string strOp2); std::string AclEx(const std::string strOp1, const std::string strOp2);};std::string strAcl(const std::string strOp1, const std::string strOp2, int nBeforeOrAfter, int* pCarry);/*返回R的N次方*/std::string strRetRN(const std::string R, const short n);void RemodePreZero(string& str);void RemodeZero(string& str);/*******************************************************************************************///acl.cpp #include "acl.h"char spliter = '.';std::string clsAdd::Acl(const std::string strOp1, const std::string strOp2){ int carry = 0; string str1(strOp1); string str2(strOp2); string strBefore1; string strBefore2; string strAfter1; string strAfter2; string strOut1; string strOut2; int npos1 = str1.find(spliter); if(string::npos == npos1) { str1 += ".0"; npos1 = str1.length() - 2; } int npos2 = str2.find(spliter); if(string::npos == npos2) { str2 += ".0"; npos2 = str2.length() - 2; } strBefore1 = str1.substr(0, npos1); strBefore2 = str2.substr(0, npos2); strAfter1 = str1.substr(npos1 + 1, str1.length() - npos1 - 1); strAfter2 = str2.substr(npos2 + 1, str2.length() - npos2 - 1); strOut1 = strAcl(strAfter1, strAfter2, 0, &carry); strOut2 = strAcl(strBefore1, strBefore2, 1, &carry); strOut1 = strOut2 + "." + strOut1; //如果和的第0位还需要进位在加结果加1 if (1 == carry) { strOut1 = "1" + strOut1; } return strOut1;}std::string clsSub::Acl(const std::string strOp1, const std::string strOp2){ //return strOp1 + strOp2; return "sub";}std::string clsMultiply::Acl(const std::string strOp1, const std::string strOp2){ clsAdd instAdd; string out; string retInt; string retDot; string strDot; int nInt = 0; int nDot = 0; int offset = 0; string s1(strOp1); int pos1 = strOp1.find(spliter); if (pos1 == string::npos) { s1 = s1 + ".0"; } int pos = strOp2.find(spliter); if (pos != string::npos) { int nLastZero = strOp2.find_first_not_of('0', pos + 1); if (nLastZero != string::npos) { offset = nLastZero - pos; nDot = atoi(strOp2.substr(pos + 1, strOp2.length() -pos - 1).c_str()); retDot = s1; for (int j = 1; j < nDot; ++j) { retDot = instAdd.Acl(retDot, s1); } int nDotPos = retDot.find(spliter); if(string::npos != nDotPos) { if (nDotPos > offset) { //20.5 retDot = retDot.substr(0, nDotPos-1) + "." + retDot.substr(nDotPos-1, retDot.length() - nDotPos+1); int nLastDotPos = retDot.find_last_of("."); if(string::npos != nLastDotPos) { retDot = retDot.substr(0, nLastDotPos) + retDot.substr(nLastDotPos + 1, retDot.length() - nLastDotPos - 1); retDot = "0" + retDot; } } else { retDot = retDot.substr(0, nDotPos) + retDot.substr(nDotPos + 1, retDot.length() - nDotPos - 1); string addzero(offset -nDotPos, '0'); retDot = "0." + addzero + retDot; } } } else { retDot = "0.0"; } } nInt = atoi(strOp2.substr(0, pos).c_str()); retInt = s1; for (int i = 1; i < nInt; ++i) { retInt = instAdd.Acl(retInt, s1); } return instAdd.Acl(retInt, retDot);}std::string clsMultiply::AclEx(const std::string strOp1, const std::string strOp2){ clsAdd instAdd; string out; int nDot1 = 0; int nDot2 = 0; int N2 = 0; int offset = 0; string s1(strOp1); int pos1 = strOp1.find(spliter); if (pos1 != string::npos) { nDot1 = s1.length() - pos1 - 1; s1 = s1.substr(0, pos1) + s1.substr(pos1 + 1, s1.length() - pos1 - 1); //去掉小数点 } string s2(strOp2); int pos2 = strOp2.find(spliter); if (pos2 != string::npos) { nDot2 = s2.length() - pos2 - 1; s2 = s2.substr(0, pos2) + s2.substr(pos2 + 1, s2.length() - pos2 - 1); } N2 = atoi(s2.c_str()); RemodePreZero(s1); out = s1; for (int i = 1; i < N2; ++i) { out = instAdd.Acl(out, s1); } RemodeZero(out); //加入小数点 offset = nDot1 + nDot2; if (offset > 0) { if (offset < out.length()) { out = out.substr(0, out.length() - offset) + "." + out.substr(out.length() - offset, offset); } else { string sz(offset - out.length(), '0'); out = sz + out; out = out.substr(0, out.length() - offset) + "." + out.substr(out.length() - offset, offset); } } RemodeZero(out); if (0 == out.find(spliter)) { out = "0" + out; } return (out);}std::string strAcl(const std::string strOp1, const std::string strOp2, int nBeforeOrAfter, int* pCarry){ int dif = 0; int nStart = 0; int preCarry = 0; string str1; string str2; int tmp; int curr; string strOut; str1 = strOp1; str2 = strOp2; if(strOp1.length() < strOp2.length()) { str1 = strOp2; str2 = strOp1; } nStart = str1.length() - 1; dif = str1.length() - str2.length(); string strAddZero(dif, '0'); if (1 == nBeforeOrAfter) { //小数点之前,在数字前面补0 str2 = strAddZero + str2; } else { //小数点之后,在数字后面补0 str2 = str2 + strAddZero; } preCarry = *pCarry; while(nStart >= 0) { tmp = (str1[nStart]-'0') + (str2[nStart]-'0'); tmp += preCarry; //当前数字+上一位的进位 if(tmp >= 10) { curr = tmp%10; preCarry = 1; } else { curr = tmp; preCarry = 0; } nStart--; char p[32] = {0}; sprintf(p, "%d", curr); string s = p; strOut = s + strOut; } *pCarry = preCarry; return strOut;}std::string strRetRN(const std::string R, const short n){ string strOut; clsMultiply multi; if( R.length() <= 0) { return "para error"; } if((n <= 0) || (n > 25)) { return "para error"; } strOut = R; for(int i = 1; i < n; ++i) { strOut = multi.AclEx(strOut, R); } return strOut;}//去掉前导0void RemodePreZero(string& str){ if (str.length() <= 0 ) { return; } int dpos = str.find(spliter); if (string::npos == dpos) { //本身没有小数点% int pos = str.find_first_not_of('0'); if (pos > 0) { str = str.substr(pos, str.length() - pos); } } else {// int pos = str.find_first_not_of('0', dpos + 1);// if ((pos > dpos) && (string::npos != pos))// {// str = str.substr(dpos - 1, str.length() - pos);// } }}//去掉多余的0void RemodeZero(string& str){ int nDotPos = -1; if (str.length() <= 0 ) { return; } //如果小数点后全是0则去掉小数点后的0 int pos = str.find(spliter); if (string::npos != pos) { int nFirstNotZero = -1; nFirstNotZero = str.find_last_not_of('0'); //小数点后最后一个不是0的字符位置 if (nFirstNotZero == pos) { //走到这里说明小数点后都是0,去掉这些0和小数点 str = str.substr(0, pos); } else if(nFirstNotZero > pos) { str = str.substr(0, nFirstNotZero+1); } } }/*********************************************************************************************///main.cpp #include <iostream>#include "acl.h"#include <cassert>using namespace std;clsAdd add;clsSub sub;clsMultiply multi;string a = "0.4321";string b = "12";string c = "00700";string out;//163.47 + 27.532 =191.002int main(){ //cout << "Hello world!" << endl; //out = add.Acl(a,b); RemodePreZero(a); RemodeZero(a); RemodePreZero(b); RemodeZero(b); //out = multi.AclEx(a,b); //assert("16" == out); out = strRetRN(a,20); //cout << out << endl; //cout << sub.Acl(a,b)<< endl; //cout << multi.Acl(a,b)<< endl; return 0;}/************************************************************************************/
- OJ_1001
- OJ_1001
- 北大OJ_1001
- 北大OJ_1001题:求正数的高精度幂
- 九度OJ_1001:计算A+B矩阵和中全零行列总数
- linux之DMA API -- 通用设备的动态DMA映射
- 风的世界里有海的七滴泪水
- 环境配置架构特点
- cocos2d一种动画的快方法
- JAVA获得程序运行时间
- OJ_1001
- JavaScript原型继承的陷阱
- 尕福(散文)
- 简明 Vim 练级攻略
- python文件操作(三)之压缩文件
- 封装
- EXPORT_SYMBOL 与 extern的区别
- Fedora14 使用root用户登录
- NSOperation and NSOperationQueue教程(翻译)