Road of poj-1001
来源:互联网 发布:微信点赞软件免费 编辑:程序博客网 时间:2024/06/09 17:21
Description
对数值很大、精度很高的数进行高精度计算是一类十分常见的问题。比如,对国债进行计算就是属于这类问题。
现在要你解决的问题是:对一个实数R( 0.0 < R < 99.999 ),要求写程序精确计算 R 的 n 次方(Rn),其中n 是整数并且 0 < n <= 25。
Input
输入包括多组 R 和 n。 R 的值占第 1 到第 6 列,n 的值占第 8 和第 9 列。
Output
对于每组输入,要求输出一行,该行包含精确的 R 的 n 次方。输出需要去掉前导的 0 后不要的 0 。如果输出是整数,不要输出小数点。
思路
将小数用数组存储,数组下标为10的幂值,即数组a第i项表示a[i]*10^i,当做整数进行运算。小数点位置可以根据输入时小数点位置进行确定。
代码
#include <iostream>#include <cstring>#define MAX 150 //(100000)^25 = 10^150using namespace std;int main(){ char s[6] = {'\0'}; char outstr[MAX] = {'\0'}; //输出字符串 int n = 0; //幂值 int pointpos = 0; //小数点位置,缺省为0 int out[MAX] = {0}; //暂存每次计算结果 int num1[MAX] = {0}; //被乘数,类似于除法定义的‘被除数’ int num2[MAX] = {0}; //乘数,类似于除法定义的‘除数’ while(cin >> s >> n) { //分析输入的数值,计算出小数位数,将小数存为整数 for(int i = 0, j = 0 ; i < 6 ; i++, j++) { if(s[i] == '.') { pointpos = n*(5-i); //记录有多少位小数 j--; } else { //这里已经将小数存为整数 num2[4-j] = s[i] - '0'; //因为s[0]对应着num2[4] } } memcpy(num1, num2, sizeof(int)*MAX); for(int i = 1 ; i<n ; i++) //第一层循环记录乘方次数 { for(int j = 0 ; j<MAX ; j++) //第二层循环遍历被乘数数组 { for(int k = 0 ; k<MAX ; k++) //第三层循环遍历乘数数组 { //核心算法是多项式相乘 out[j+k] = out[j+k] + num1[j] * num2[k]; //一旦大于等于10,向后进1位 for(int l = j+k ; l<MAX ; l++) { if(out[l] >= 10) { out[l+1] += out[l]/10; out[l] = out[l]%10; } } } } memcpy(num1, out, sizeof(int)*MAX); //将计算得到的out赋给num1,准备下一次计算。 memset(out, 0, MAX*sizeof(int)); //将out清空,用来存放下一次的中间计算结果。 //这样也就导致最后的计算结果存放在num1中 } int flag = 0; //num1从后向前遍历,跳过整数的前置零 for(int i = MAX-1, j = 0 ; i>=0 ; i--) { if(num1[i] == 0 && flag == 0 && i != pointpos - 1) { continue; } else { if( i == pointpos - 1) //到达小数点位置 { outstr[j++] = '.'; } outstr[j++] = num1[i] + '0'; flag = 1; } } //outstr从后向前遍历,去除小数的后置零 for(int i = (signed)strlen(outstr)-1 ; i>=0 ; i--) { if(outstr[i] == '0') { outstr[i] = '\0'; if(outstr[i-1] == '.') //结果为整数,将小数点赋为\0 { outstr[i-1] = '\0'; break; } } else { break; } } cout << outstr << endl; //清空num1,num2,outstr,out在之前已经清空。 memset(num1, 0, sizeof(int)*MAX); memset(num2, 0, sizeof(int)*MAX); memset(outstr, '\0', sizeof(char)*MAX); } return 0;}
注意事项
1、前置零后置零的处理。
2、整数的处理。
3、每次输入处理后一定要及时进行清零。
总结
总体来讲思路比较清楚,实现起来不困难,多项式相乘的算法可能算一个不大的点。主要的困难在于如何把所有情况考虑在内,需要好好构思思路以及测试数据。ps. 这个多项式相乘写的巨丑无比,之后应该会进行改写~
阅读全文
0 0
- Road of poj-1001
- Road of poj-1002
- The road of iTour
- the road of future
- road of hibernate
- the road of IELTS
- the road of IELTS
- poj 3352 Road Construction
- POJ 3352 Road Construction
- POJ 3352: Road Construction
- poj 3433 Road Accident
- POJ 3352 Road Construction
- POJ - 3846 Mountain Road
- poj 3352 Road Construction
- poj 3352 Road Construction
- POJ 3352 Road Construction
- poj 3352 Road Construction
- POJ 3352 Road Construction
- python-scikit-learn-DBSCAN
- Python基本数据类型
- 虚拟机下安装CentOS 7.4教程
- windows(64位)下使用curl命令
- 各种依赖
- Road of poj-1001
- 思维模型
- ECMA-262-5 词法环境:ECMA实现(四)--- 标识符解析及其他
- 漫谈千亿级数据优化实践:数据倾斜(纯干货)
- ACdream 1083
- 剑指offer
- 顺序栈基本运算
- 单例模式
- 项俊平:深度强化学习的交通信号优化控制浅析