poj-1001 高精度幂

来源:互联网 发布:window7下安装ubuntu 编辑:程序博客网 时间:2024/05/21 08:47
求高精度幂
Time Limit: 500MS Memory Limit: 10000KTotal Submissions: 114985 Accepted: 27919

Description

对数值很大、精度很高的数进行高精度计算是一类十分常见的问题。比如,对国债进行计算就是属于这类问题。

现在要你解决的问题是:对一个实数R( 0.0 < R < 99.999 ),要求写程序精确计算 R 的 n 次方(Rn),其中n 是整数并且 0 < n <= 25。

Input

T输入包括多组 R 和 n。 R 的值占第 1 到第 6 列,n 的值占第 8 和第 9 列。

Output

对于每组输入,要求输出一行,该行包含精确的 R 的 n 次方。输出需要去掉前导的 0 后不要的 0 。如果输出是整数,不要输出小数点。

Sample Input

95.123 120.4321 205.1234 156.7592  998.999 101.0100 12

Sample Output

548815620517731830194541.899025343415715973535967221869852721.0000000514855464107695612199451127676715483848176020072635120383542976301346240143992025569.92857370126648804114665499331870370751166629547672049395302429448126.76412102161816443020690903717327667290429072743629540498.1075960194566517745610440100011.126825030131969720661201

 

解题时间:2013/3/23 - 2013/3/24

        

解题思路:

     用数组表示数串,每一个数组元素存储数串的一位。

     数字串反向存储,如123.456   存储为654321  记录长度和小数点的位置,这样存储是为了方便计算。

     所有的乘法都用累加来实现。

 

代码:

#include <stdio.h>void ADD(int arr1[],int arr2[],int *L1,int L2,int *P1,int P2){    int temp;    int L;    int i;    if(*P1>=P2)    {        temp=*P1-P2;        L=*L1>(L2+temp)?*L1:(L2+temp);        for(i=temp; i<L; i++)        {            arr1[i]+=arr2[i-temp];        }        *L1=L;    }    else    {        temp=P2-*P1;        L=(*L1+temp)>L2?(*L1+temp):L2;        for(i=L-1; i>=0; i--)        {            if(i>=temp) arr1[i]=arr1[i-temp];            else arr1[i]=0;        }        for(i=0; i<L; i++)        {            arr1[i]+=arr2[i];        }        *L1=L;        *P1=P2;    }    //规范化    for(i=0; i<*L1; i++)    {        if(arr1[i]>=10)        {            arr1[i]-=10;            arr1[i+1]++;        }    }    if(arr1[i]==1)        *L1+=1;}//arr2复制到arr1void COPY(int arr1[],int arr2[],int *L1,int L2,int *P1,int P2){    int i=0;    for(; i<L2; i++)    {        arr1[i]=arr2[i];    }    while(i<150)    {        arr1[i]=0;        i++;    }    *L1=L2;    *P1=P2;}//规范化得到t1,t2的值void NORMALIZE(int arr[],int L,int P,int *t1,int *t2){    *t1=0,*t2=0;    int i;    for(i=0; (i<P-1)&&(arr[i]==0); i++)    {        *t1=*t1+1;    }    for(i=L; (i>=P)&&(arr[i-1]==0); i--)    {        *t2=*t2+1;    }}void SETZERO(int arr[],int *L,int *P){    int i;    for(i=0; i<*L; i++)    {        arr[i]=0;    }    *L=0;    *P=0;}int main(){    char str[7];//输入的串    int n;    int sumNow[150] = {0};//当前值    int sumNowL=0,sumNowP=0;//串长度,不包括小数点,小数点位置如123.456为4    int sumLast[150] = {0};//每次幂之后的值    int sumLastL=0,sumLastP=0;    int sumTemp[150] = {0};//中间值    int sumTempL=0,sumTempP=0;    int s[6]= {0}; //输入的串    int sL,sP;    int i,j;    int t1,t2;    while(scanf("%s %d",str,&n)!=EOF)    {        SETZERO(sumLast,&sumLastL,&sumLastP);        SETZERO(sumTemp,&sumTempL,&sumTempP);        //将输入的串用数组的形式表示        sL=6;        sP=6;        j=0;        for(i=5; i>=0; i--)        {            if(str[i]=='.')            {                sL=5;                sP=6-i;            }            else            {                s[j]=str[i]-48;                j++;            }        }        //计算每次幂后的结果        COPY(sumNow,s,&sumNowL,sL,&sumNowP,sP);        COPY(sumLast,s,&sumLastL,sL,&sumLastP,sP);        n--;        while(n)        {            SETZERO(sumNow,&sumNowL,&sumNowP);            for(i=0; i<sL; i++)            {                if(s[i]==0)                    continue;                COPY(sumTemp,sumLast,&sumTempL,sumLastL,&sumTempP,sumLastP);                for(j=1; j<s[i]; j++)                {                    ADD(sumTemp,sumLast,&sumTempL,sumLastL,&sumTempP,sumLastP);                }                sumTempP=sumTempP+sP-i-1;//L是否要变                ADD(sumNow,sumTemp,&sumNowL,sumTempL,&sumNowP,sumTempP);            }            n--;            COPY(sumLast,sumNow,&sumLastL,sumNowL,&sumLastP,sumNowP);        }        NORMALIZE(sumNow,sumNowL,sumNowP,&t1,&t2);        for(i=sumNowL; i>0; i--)        {            if(t2)            {                t2--;            }            else            {                if(i>t1)                    printf("%d",sumNow[i-1]);            }            if((i==sumNowP)&&(t1+1!=sumNowP))            {                printf(".");            }        }        printf("\n");    }    return 0;}


 

 

 

 

 

 

 

 

 

 

 

原创粉丝点击