您的位置:首页 > 编程语言 > C语言/C++

(HDU 1063)Exponentiation(c++实现)

2018-04-10 10:11 387 查看
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 R n 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

C++

while(cin>>s>>n)

{



}

c

while(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 /

{



}

http://poj.org/problem?id=1001

这里用C++来模拟大数的乘方,用java写过的估计都不想再看这个程序了。

解析见程序。

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include<sstream>
#include<set>
#include <cstdlib>
#include<map>
using namespace std;
string xsum1(string a,char b)         //一个多位数a和一个一位数b相乘返回结果
{
string c="0";                     //用c字符串来保存相乘的结果
int yu=0;                         //用来模拟保存要进位的数
for(int j=a.length()-1;j>=0;j--)  //从后向前相乘
{
c.insert(0,1,(a[j]-'0')*(b-'0')%10+yu+'0');  //相乘的结果+上之前进上来的yu,再插入到字符串c的0的位置
yu=(a[j]-'0')*(b-'0')/10;                    //之后把要进位的保存到yu中
if(c[0]-'0'>=10)
{
c[0]=(c[0]-'0')%10+'0';                  //如果此时这一位还大于10那么取余下次要进的位数大小+1
yu++;
}
}
if(yu!=0)                                        //如果依次相乘完之后的要进位数的大小不为0再把yu插入到c
c.insert(0,1,yu+'0');
c.erase(c.length()-1,1);                         //把c初始时那个'0'删除
return c;
}
string xsum2(string a,string b)                      //借助之前的xsum1函数来求多位数相乘的结果
{                                                   //思想就是模拟多位数相乘时进行的竖式运算(依次用个.十.百...位和因数相乘在求和)
string c,c1;
int k,u=1,yu;                                   //u的作用是模拟多位数相乘过程中求和位置正确对齐,不理解的话耐心走遍这个函数
for(int i=b.length()-1;i>=0;i--)                //同样从尾部开始循环
{
yu=0;                                       //yu同样代表要进位数字的大小
if(i==b.length()-1)                         //把b的个位数和a相乘的结果给c,以后才能模拟b的十位数字和a相乘后求和的运算
c=xsum1(a,b[i]);
else
{
c1=xsum1(a,b[i]);
k=c1.length();
for(int j=c.length()-1-u;j>=0;j--)      //进入了模拟多位数相乘过程中求和的过程
{
c[j]+=c1[--k]-'0'+yu;
if(c[j]-'0'>=10)
{
yu=(c[j]-'0')/10;
c[j]=(c[j]-'0')%10+'0';
}
else
{yu=0;}
}
if(yu&&!k)                              //如果c1的所有数字都完成了求和过程且yu不为0,就把yu插入到c最前面
c.insert(0,1,'0'+yu);
while(k--)                              //如果ci还有数字没完成求和过程,就把它们依次插入到c的前面
{
c.insert(0,1,c1[k]+yu);
yu=0;
}
u++;                                    //u++,如果是第一次循环,那么,下次就用c1的最后一位和c的倒数第3位开始依次求和
}
}
return c;
}
int main()
{
string a,b;
int n,N,point,c;
while(cin>>a>>n)
{
N=n;
c=0;
if(a[0]=='.')                               //这是题目的细节地方:输入.123和0.123是一样的,不过输出不要小数点前面的0
{
a.erase(a.find('.'),1);                 //开始就是'.',就删除'.'插入'0'进行之后的运算
a.insert(0,1,'0');
c=-1;
}
else if(a.find('.')>0&&a.find('.')<=a.length()-1)  //如果小点在数的中间的情况
{
point=a.length()-a.find('.')-1;                 //先判断出时是几位小数并保存给point为了方便以后的运算还要删除'.'
a.erase(a.find('.'),1);
c=1;
}
b=a;
while(--n)
{
a=xsum2(a,b);                               //计算a^n,就来模拟n个a相乘
}
if(c==1)                                       //如果小数点在数中间就把前面和后面的'0'删除
{
a.insert(a.length()-N*point,1,'.');
while(a[a.length()-1]=='0')
a.erase(a.length()-1,1);
while(a[0]=='0')
a.erase(0,1);
}
else if(c==-1)                                  //a是以'.'开头的情况,添加'.',删除之前添加的'0'并删除字符串后面的'0'
{
a.insert(0,1,'.');
a.erase(1,1);
while(a[a.length()-1]=='0')
a.erase(a.length()-1,1);
}
if(a[a.length()-1]=='.')                        //如果是以'.'结尾的还要把结尾的点删除
a.erase(a.length()-1,1);
cout<<a<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  北大ACM