解题思路
这道题属于高精度乘法运算,要求输入一个实数R一个指数N,求实数R的N次方,由于R有5个数位,而N又特别大,因此用C++自带的数据类型放不下.
解题思路是通过数组储存每次乘积结果和底数的每一位数,按照乘法上下算式的方法,计算底数乘数数组每一位与临时结果数组的每一位的乘积,(因为算术运算中是从数的后面往前算的,这里存储数时要先倒序,输出时再颠倒过来,)然后偏移相加,判断得出的临时结果数组的每一位是否大于9,通过除法和取模实现进位和取余.至此得出一个有很多无效数位的结果数组(很多无效的0).
最后判断结果数组的每一位是否为0,先输出小数点前面的数,后输出小数点后面的数,最终得出乘法结果.
这个题目实际上考的是高精度乘法,高精度的其他运算和这个差不多,原理都是一样的.
Description
Problems involving the computation of exact values of very large magnitude and precision are common. For example, the computation of the national debt is a taxing experience for many computer systems.
This problem requires that you write a program to compute the exact value of Rn where R is a real number ( 0.0 < R < 99.999 ) and n is an integer such that 0 < n <= 25.
Input
The input will consist of a set of pairs of values for R and n. The R value will occupy columns 1 through 6, and the n value will be in columns 8 and 9.
Output
The output will consist of one line for each line of input giving the exact value of R^n. Leading zeros should be suppressed in the output. Insignificant trailing zeros must not be printed. Don't print the decimal point if the result is an integer.
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
Hint
If you don't know how to determine wheather encounted the end of input:
s is a string and n is an integer
SourceCode
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string r; //底数
int n,dianwei; //指数,小数点位置
const int len=200; //数位长度
short result[len],jieguo[len],chengshu[6]; //最终结果,临时结果,底数乘数
while(cin>>r>>n)
{
//初始化
for(int i=0;i<len;++i) jieguo[i]=result[i]=0;
for(int i=0;i<6;++i) chengshu[i]=0;
dianwei=0;
//得到底数小数点位置
size_t pos = r.find('.');
//如果底数中有小数点 获取小数点后面有多少位数
if(pos!=string::npos) dianwei=(5-pos)*n;
//把底数中所有不是小数点的数字挑出来转换为int并赋给最终结果,临时结果,底数乘数 得到的是3个5位前后颠倒的数组 之所以颠倒是因为乘法是从后往前乘的
for(int i=5,j=0;i>=0;--i)
{
if(r[i]!='.')
{
jieguo[j]=result[j]=chengshu[j]=r[i]-'0';
++j;
}
}
//当指数大于1时 进行以下运算 等于1时跳过这段程序直接输出
while(n>=2)
{
--n;
//初始化最终结果数组
for(int i=0;i<len;++i) result[i]=0;
for(int i=0;i<5;++i) //从底数乘数的每一位
{
//底数乘数每位数和临时结果每位数相乘的临时变量
int temp;
for(int j=0;j<len;++j) //乘以临时结果的每一位
{
//如果底数乘数某一位是0 没必要乘下去了 跳出当前循环
if(chengshu[i]==0) break;
temp=chengshu[i]*jieguo[j];
//i+j实现乘法相加时的移位
result[i+j]+=temp;
//++t遍历所有结果数组中大于9的数 用除法和取模实现进位和余数
for(int t=i+j;result[t]>9;++t)
{
result[t+1]+=result[t]/10;
result[t]=result[t]%10;
}
}
}
//把一次乘法后的结果赋给临时结果来进行下次乘方
for(int i=0;i<len;++i) jieguo[i]=result[i];
}
//获取最终结果从后数第一个不为0的数作为第一个数的标志位 之所以从后数 是因为之前颠倒的数要颠倒回来了
int firstindex=-1;
for(int i=len;i>=dianwei;--i)
{
if(result[i]>0)
{
firstindex=i;
break;
}
}
//获取 最终结果从前数第一个不为0的数作为最后一个数的标志位
int lastindex=-1;
for(int i=0;i<dianwei;++i)
{
if(result[i]>0)
{
lastindex=i;
break;
}
}
//如果最终结果数组中不全是0 倒序输出结果数组中小数点前面的数
if(firstindex!=-1)
{
while(firstindex>=dianwei)
{
cout<<result[firstindex];
--firstindex;
}
}
//如果最终结果数组中不全是0 倒序输出结果数组中小数点后面的数
if(lastindex!=-1)
{
cout<<'.';
--dianwei;
while(dianwei>=lastindex)
{
cout<<result[dianwei];
--dianwei;
}
}
cout<<endl;
}
}
附录:
一.高精度数的存储
1.字符串输入
#include <iostream>
#include <cstring>
using namespace std;
const int N=100;//最多100位
int main()
{
int a[N+1],i;
string s1;
cin>>s1;//数s1
memset(a,0,sizeof(a)); //数组清0
a[0]=s1.length(); //位数
for(i=1;i<=a[0];i++)
{
a[i]=s1[a[0]-i]-'0';//将字符转为数字并倒序存储.
}
return 0;
}
2.直接读入
#include <iostream>
using namespace std;
const int N=100;//最多100位
int main()
{
int a[N+1],i,s,key;
cin>>key;//数key
memset(a,0,sizeof(a)); //数组清0
i=0;//第0位
while(key) //当key大于0
{
a[++i]=key%10;//取第i位的数
key=key/10;
}
a[0]=i; //共i位数
return 0;
}
3.直接初始化(用a[]存储)
- 初始化为0: memset(a,0,sizeof(a));
- 初始化为1: memset(a,0,sizeof(a));a[0]=1;a[1]=1;
以下程序都只写函数,不写完整程序,所有高精度数存储都满足上述约定。
二.高精度数比较
int compare(int a[],int b[]) //比较a和b的大小关系,若a>b则为1,a<b则为-1,a=b则为0
{
int i;
if (a[0]>b[0]) return 1;//a的位数大于b则a比b大
if (a[0]<b[0]) return -1;//a的位数小于b则a比b小
for(i=a[0];i>0;i--) //从高位到低位比较
{
if (a[i]>b[i]) return 1;
if (a[i]<b[i]) return -1;
}
return 0;//各位都相等则两数相等。
}
三、高精度加法
int plus(int a[],int b[]) //计算a=a+b
{int i,k;
k=a[0]>b[0]?a[0]:b[0]; //k是a和b中位数最大的一个的位数
for(i=1;i<=k;i++)
{
a[i+1]+=(a[i]+b[i])/10; //若有进位,则先进位
a[i]=(a[i]+b[i])%10; //计算当前位数字,注意:这条语句与上一条不能交换。
}
if(a[k+1]>0)
{
a[0]=k+1; //修正新的a的位数(a+b最多只能的一个进位)
}
else
{
a[0]=k;
}
return 0;
}
四、高精度减法
int gminus(int a[],int b[]);//计算a=a-b,返加符号位0:正数 1:负数
{
int flag,i
flag=compare(a,b); //调用比较函数判断大小
if (falg==0)//相等
{
memset(a,0,sizeof(a));return 0; //若a=b,则a=0,也可在return前加一句a[0]=1,表示是 1位数0
}
if(flag==1) //大于
{
for(i=1;i<=a[0];i++)
{
if(a[i]<b[i]){ a[i+1]--;a[i]+=10;} //若不够减则向上借一位
a[i]=a[i]-b[i];
}
while(a[a[0]]==0) a[0]--; //修正a的位数
return 0;
}
if (flag==-1)//小于 则用a=b-a,返回-1
{
for(i=1;i<=b[0];i++)
{
if(b[i]<a[i]){ b[i+1]--;b[i]+=10; //若不够减则向上借一位
}
a[i]=b[i]-a[i];}
a[0]=b[0];
while(a[a[0]]==0) a[0]--; //修正a的位数
return -1;
}
}
五、高精度乘法(高精度乘单精度数,单精度数是指通常的整型数)
int multi1(int a[],long key) //a=a*key,key是单精度数
{
int i,k;
if (key==0){memset(a,0,sizeof(a));a[0]=1;return 0;} //单独处理key=0
for(i=1;i<=a[0];i++)
{
a[i]=a[i]*key;//先每位乘起来
}
for(i=1;i<=a[0];i++)
{
a[i+1]+=a[i]/10;a[i]%=10; //进位
}
//注意上一语句退出时i=a[0]+1
while(a[i]>0)
{
a[i+1]=a[i]/10;a[i]=a[i]%10;i++;a[0]++]; //继续处理超过原a[0]位数的进位,修正a的位数
}
return 0;
}
1001. Exponentiation高精度运算总结的更多相关文章
-
POJ 1001 Exponentiation(大数运算)
POJ 1001 Exponentiation 时限:500 ms 内存限制:10000 K 提交材料共计: 179923 接受: 43369 描述:求得数R( 0.0 < R < ...
-
百炼1001: Exponentiation 解题
链接:http://bailian.openjudge.cn/practice/1001/ 思路 乍一看是很简单的题目,但是答案必须高精度输出,因此需要手动实现一个高精度运算方法.如果直接使用int, ...
-
高精度运算专题3-乘法运算(The multiplication operation)
这个专题呢,我就来讲讲高精度的乘法,下面是三个计算乘法的函数,第一个函数是char类型的,要对字符串进行数字转换,而第二个是两个int类型的数组,不用转换成数字,第三个则更为优化,用a数组-b数组放回 ...
-
[code]高精度运算
数组存储整数,模拟手算进行四则运算 阶乘精确值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #includ ...
-
系统的讲解 - PHP 浮点数高精度运算
目录 概述 浮点数运算的"锅" 任意精度数学函数 常用数值处理方案 扩展 小结 概述 记录下,工作中遇到的坑 ... 关于 PHP 浮点数运算,特别是金融行业.电子商务订单管理.数 ...
-
#C++初学记录(高精度运算)(加法)
高精度运算 不管是int还是double亦或者long long ,这些定义变量都有数据范围的一定限制,在计算位数超过十几位的数,也就是超过他们自身的数据范围时,不能采用现有类型进行计算,只能自己通过 ...
-
ICPC Asia Nanning 2017 F. The Chosen One (高精度运算)
题目链接:The Chosen One 比赛链接:ICPC Asia Nanning 2017 题意 \(t\) 组样例,每组给出一个整数 \(n(2\le n\le 10^{50})\),求不大于 ...
-
算法模板 - C++ 高精度运算
C++算法板子 高精度 高精度推荐用python来写,python有大整数,这里写的是关于C++的高精度运算模板 1.高精 * 低精 #include <iostream> #includ ...
-
poj 1001 Exponentiation 第一题 高精度 乘方 难度:1(非java)
Exponentiation Time Limit: 500MS Memory Limit: 10000K Total Submissions: 138526 Accepted: 33859 ...
随机推荐
-
static成员变量与返回对象的引用
(1)用static修饰类成员变量(属性),表明该变量是静态的,无论创建多少对象,都只创建一个一个静态属性副本,也就是对象们共享同一个静态属性,这个方法常用的一个用途就是用来计算程序调用了多少次这个类 ...
-
使用hexo+github搭建免费个人博客详细教程
[TOC] 本文目录(注意无法点击): 前言 体验更加排版请访问原文链接:http://blog.liuxianan.com/build-blog-website-by-hexo-github.htm ...
-
Heritrix源码分析(十二) Heritrix的控制中心(大脑)CrawlController(一)(转)
本博客属原创文章,欢迎转载!转载请务必注明出处:http://guoyunsky.iteye.com/blog/650694 本博客已迁移到本人独立博客: http://www.yun5u.com/ ...
-
IOS学习笔记1`
写了IOS的Hello World,记事本写的.除了一些基本的语法外,最主要的收获就是路径问题了. 直接把文件拖入终端,就会显示文件的完全限定名了.
-
解决 android.view.ViewGroup$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams
错误日志1: 06-13 10:55:50.410: E/KVLog(1129): Error info:java.lang.ClassCastException: android.widget.Li ...
-
C#操作Excel文件(转)
摘要:本文介绍了Excel对象.C#中的受管代码和非受管代码,并介绍了COM组件在.net环境中的使用. 关键词:受管代码:非受管代码:Excel对象:动态连接库 引言 Excel是微软公司办公自动化 ...
-
Pig系统分析(6)-从Physical Plan到MR Plan再到Hadoop Job
从Physical Plan到Map-Reduce Plan 注:由于我们重点关注的是Pig On Spark针对RDD的运行计划,所以Pig物理运行计划之后的后端參考意义不大,这些部分主要分析流程, ...
-
Linux Shell : Test命令参数解析
格式: test conditions test -n string : string 不为空 test -z string : string 为空 test int1 -eq int2 : int ...
-
Postgres Linux 维护 随笔1(启动篇)
关于postgres 起停操作随笔 Linux 环境下,对Postgres 起停常用代码 Postgres 启动 : pg_ctl start Postgres 停止 : pg_ctl stop Po ...
-
反射实现java深度克隆
一.克隆 有时想得到对象的一个复制品,该复制品的实体是原对象实体的克隆.复制品实体的变化不会引起原对象实体发生变化,这样的复制品称为原对象实体的克隆对象或简称克隆. 1.浅复制(浅克隆) 概念:被复制 ...