poj 1001 Exponentiation(高精度运算)
来源:互联网 发布:企业网络信息安全培训 编辑:程序博客网 时间:2024/05/22 13:18
This problem requires that you write a program to compute the exact value of R nwhere R is a real number ( 0.0 < R < 99.999 ) and n is an integer such that 0 < n <= 25.
95.123 120.4321 205.1234 156.7592 998.999 101.0100 12
548815620517731830194541.899025343415715973535967221869852721.0000000514855464107695612199451127676715483848176020072635120383542976301346240143992025569.92857370126648804114665499331870370751166629547672049395302429448126.76412102161816443020690903717327667290429072743629540498.1075960194566517745610440100011.126825030131969720661201
s is a string and n is an integer
C++while(cin>>s>>n){...}cwhile(scanf("%s%d",s,&n)==2) //to see if the scanf read in as many items as you want/*while(scanf(%s%d",s,&n)!=EOF) //this also work */{...}
思路:这道题目考查高精度乘法的计算。
要解决这道题目并不能使用cmath里的pow函数,而必须自己模拟乘法的计算过程,以实现高精度结果的输出。
所幸输入的底数一定是5位数,这给我们创造了一点方便。
我们可以将底数以字符串的形式读入,然后计算出结果中小数点应该在多少位,比如第一个结果应该是3*12=36。
关键的部分在于数据的处理,这里我的办法是倒序去掉小数点逐位存储,比如95.123,最后应该是用一个大小为5的数组存储为[3][2][1][5][9],每个单元只存一个数位。这里涉及到存储类型的问题,为了计算方便,最好用short类型的数组。
存储结果的数组需要开到150,我没有精确计算,大概是这么大,我选择160。
为了计算方便,我们不把数字多余的0去掉,而是在最后判断小数点的位置,然后输出该输出的数位。
每次乘法,都是用题目给的r乘上你上一次得出的结果,如果是第一次计算,那么就是r,计算的结果直接加到一个初始化为0的160大小的数组里面,注意是加。乘法的过程很容易模拟出来,就是让乘数让乘数第一位把你的结果的所有位乘一遍,然后再让第二位乘,注意加进数组时,有一个偏移量,乘法竖式都是这么写的,大家体会下。
为什么使用倒序存储的数组呢,想想上面对竖式的模拟就很容易明白了,从0位开始乘,结果也从0位开始存,非常方便。这样得出的结果也是倒序的。
输出结果时要小心,因为数组中存储的数位是倒序的,且没有小数点,需要计算从两边向中间的小数点方向第一个不为0数的位置,这是为了避免输出不必要的0而导致WA。
给出一个计算过程演示:
比如输入为1.0002 3
20001
× 2
------------
40002
此时结果数组中存储的是40002
20001
× 0
------------
40002
00000
此时结果数组中存储的是40002中间省略两步
20001
× 1
------------
40002
00000
00000
00000
20001
此时结果数组中存储的是400040001
400040001
× 2------------------
这里我就不计算了,最后结果数组里面存的是8000210060001
根据4*3=12,可以知道小数点应插在12号位,也就是11号位后面
800021006000.1
两边向中间,第一个不为0的数恰好就是两边,输出为
1.000600120008
代码:
#include<iostream>#include<string>#include<string.h>using namespace std;int main(){ string r; int n; const int len=160; int result[len],a[len],b[6]; while(cin>>r>>n) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(result,0,sizeof(result)); int i,j,signi=0;//signi标记小数点的位置 size_t pos=r.find(".");//寻找小数点的位置 if(pos!=string::npos)//判断是否是整数 signi=(5-pos)*n;//记录有多少位小数 for(i=5,j=0; i>=0; i--) { if(r[i]!='.') { result[j]=a[j]=b[j]=r[i]-'0'; j++; } } while(n>=2)//注意n=1的情况 { n--; memset(result,0,sizeof(result)); for(i=0; i<5; i++) { for(j=0; j<len; j++) { if(!b[i]) break; result[i+j]+=a[j]*b[i]; result[i+j+1]+=result[i+j]/10;//处理进位 result[i+j]=result[i+j]%10; } } memcpy(a,result,sizeof(result));//转存结果,以便下次计算// for(i=0; i<len; i++)// a[i]=result[i]; } int fronti=-1; for(i=len-1; i>=signi; i--)//去除前面多余的0 { if(result[i]) { fronti=i; break; } } int lasti=-1; for(i=0; i<signi; i++)//去除后面多余的0 { if(result[i]) { lasti=i; break; } } if(fronti!=-1) { for(i=fronti; i>=signi; i--) cout<<result[i]; } if(lasti!=-1) { cout<<"."; for(i=signi-1; i>=lasti; i--) cout<<result[i]; } cout<<endl; } return 0;}
- poj 1001 Exponentiation(高精度运算)
- POJ 1001 Exponentiation - 高精度高位数运算
- POJ-1001 Exponentiation 高精度
- Exponentiation - POJ 1001 高精度
- poj 1001 Exponentiation(高精度乘法)
- poj 1001 Exponentiation(求高精度幂)
- POJ 1001 Exponentiation (高精度/大数乘法)
- POJ 1001 Exponentiation(高精度乘法)
- POJ 1001:Exponentiation —— 高精度浮点数运算
- poj 1001 (Exponentiation) 高精度乘法
- poj 1001 Exponentiation 高精度乘方
- 【POJ】 1001-Exponentiation 【高精度乘法】
- POJ 1001 Exponentiation (Java高精度)
- POJ 1001 Exponentiation 高精度乘法
- POJ 1001 Exponentiation 高精度指数
- poj 1001 Exponentiation 高精度乘法
- poj 1001 uva 748 Exponentiation(高精度小数乘法)
- poj 1001 Exponentiation 高精度
- jms-activemq消息队列
- 网页元素居中笔记
- Qt学习笔记2:QMainWindow和QWidget的区别
- RxJava 入门之关键的类
- Spring开发之静态工厂创建对象+动态工厂创建对象+构造方法创建对象+set方法注入+构造方法注入
- poj 1001 Exponentiation(高精度运算)
- 分糖果
- Tensorflow入门教程-1
- 105. Construct Binary Tree from Preorder and Inorder Traversal,前序+中序 构建 树
- Android AnimationDrawable 使用示例
- JQuery中prop跟attr的区别
- ORM框架-mybatis的一般规范
- android 输入事件
- PHP设计模式——单例模式