其他分享
首页 > 其他分享> > [POJ] 1001 Exponentiation

[POJ] 1001 Exponentiation

作者:互联网

                                                                             Exponentiation

Time Limit: 500MS Memory Limit: 10000K
Total Submissions: 188955 Accepted: 45370

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

解题思路

本题考察高精度乘法计算,有以下几个关键点:

1、将R以字符串形式读入,通过判断R中小数点的位置,得到最终的计算结果中有多少位小数,接着将去除小数点后的整数保存到sum中,方便下一步运算。以第一个测试用例为例,最终计算结果包含3*12=36位小数,去除小数点后sum=95123。

2、通过calculate()迭代模拟乘法计算,需要注意函数中初始化和进位的处理。

3、最后,对前缀零和后缀零进行处理,判断计算结果中是否包含小数并分类输出。

这道题的测试用例比较强大,边界条件没有考虑清楚的话容易Wrong Answer,在此给出几个比较有代表性的测试用例

代码注释比较详细,G++下已AC。

#include <iostream>
#include <string.h>
using namespace std;
int ans[125];//保存输出结果。极端情况为r=.000001,由于n<=25,故数组最大为5*25=125。
int m;//m保存计算结果的位数
//calculate模拟乘法计算过程
void calculate(int num){
    //初始化m=1,ans[0]=1,第一次运行函数时,num的每一位被保存到ans[]中
    for(int i=0;i<m;i++)//极端情况为999999*9,不超过int范围,先保存计算结果再考虑进位
        ans[i]*=num;
    for(int i=0;i<m-1;i++){//进位处理
        ans[i+1]+=ans[i]/10;
        ans[i]%=10;
    }
    int last=ans[m-1];//last保存最后一位数字,如12
    for(;last>0;m++){//处理最后一位数字,保存到ans[]中
        ans[m-1]=last%10;
        last/=10;
    }
    return;
}

int main()
{
    string r;
    int n;
    while(cin>>r>>n){
        int sum=0,point=0;
        memset(ans,0,sizeof(ans));
        ans[0]=1;//初始化,方便后面的计算
        for(int i=0;i<r.length();i++){
            if(r[i]=='.'){
                point=(r.length()-i-1)*n;//point保存最后的计算结果有多少小数位
            }
            else{
                //sum保存去除小数点后的数据,如123.45被转化为12345
                sum*=10;
                sum+=r[i]-'0';
            }
        }
        if(sum==0)
            {cout<<"0"<<endl;continue;}
        m=1;//初始化,方便后面的计算
        for(int i=0;i<n;i++)
            calculate(sum);
        m--;//由于culculate中最后一个for循环退出时执行了m++
        int temp=0;
        for(int i=0;i<m;i++){
            if(ans[i]!=0)
                {temp=i;break;}//temp保存第一位不为0的数的位置
        }
        if(point-temp<=0){//结果不含小数点的情况
            for(int i=m-1;i>=point;i--)//输出整数部分
                cout<<ans[i];
        }
        else{//结果含小数点的情况
            if(point>m) m=point;//r含较多前缀0时会导致m<=point,导致输出错误,如r=.00001
            for(int i=m-1;i>=point;i--)//输出整数部分
                cout<<ans[i];
            cout<<".";
            for(int i=point-1;i>=temp;i--)//输出小数部分
                cout<<ans[i];
        }
        cout<<endl;
    }
    return 0;
}

 

标签:point,int,Exponentiation,value,will,POJ,ans,1001,小数
来源: https://blog.csdn.net/weixin_34088916/article/details/97418706