您的位置:首页 > 其它

POJ-1001 求高精度幂-大数乘法系列

2014-10-06 13:35 926 查看
    题目描述:对一个实数R( 0.0 < R < 99.999 ),要求写程序精确计算 R 的 n 次方(Rn),其中n 是整数并且 0 < n <= 25。输入数据中每行1-6列为R的值,n的值为8-9列。对于输出答案,需要去除无用的前导0和后续0。整数的话不要输出小数点。

    这是一个高精度乘法的问题,只是比普通的大数乘法多了小数点处理和冗余0处理的问题。

    首先需要把输入数据的小数点去掉,并记录小数点位置(变量为int point),最后处理时,小数点位置在point * n。此时注意对整数需要特殊处理一下。

    对于大数相乘问题,可以手写几遍乘法,观察一下过程,然后用程序模拟。这里给出一种相对另类的乘法过程,即在最高位预留出一位最高位进位位,然后从数字高位向数字低位逐位做乘法并累加,然后再从低位结果向高位结果处理。

    对于小数点和冗余0处理的先后问题,要先处理小数点,把最终结果加上小数点后,再消去冗余0。

    下面是AC代码:

# include<stdio.h>
# include<string.h>
# include<stdlib.h>
int _res[1000];//此处数组若为char型会发生溢出,注意注意
void mul(char a[],char b[])
{
int i,j,la,lb;
la=strlen(a);
lb=strlen(b);
for (i=0; i<la+lb; i++)
_res[i]=0;
for (i=0; i<la; i++)
for (j=0; j<lb; j++)
_res[i+j+1]+=(a[i]-'0')*(b[j]-'0');
for (i=la+lb-1; i>0; i--)
{
if (_res[i]>=10)
{
_res[i-1]+=_res[i]/10;
_res[i]%=10;
}
}
i=0;
while (_res[i]==0)
i++;
for (j=0; i<la+lb; i++,j++)
a[j]=_res[i]+'0';
a[j]=0;
}
int main()
{
char res[1000],r[10];
int n;
while(~scanf("%s %d",r,&n))
{
char m[10]= {0};
int i,j,point=-1,judge=0;
for(i=0; i<1000; ++i) res[i]=0;
for(i=0,j=0; i<6; ++i)
if(r[i]!='.') m[j++]=r[i];
else point=strlen(r)-j-1;
res[0]='1';
point*=n;
while(n--)
{
mul(res,m);
}
if(point>0)
{
for(i=0,j=strlen(res)-1; i<=j; ++i,--j) res[i]=res[i]+res[j]-(res[j]=res[i]);//结果逆置后方便添加小数点
i=strlen(res);
if(point>=i)
{
for(i=strlen(res); i<=point; ++i) res[i]='0';
res[point]='.';
res[point+1]=0;
}
else
{
while(i>=point)
{
res[i]=res[i-1];
--i;
}
res[point]='.';
}
for(i=0,j=strlen(res)-1; i<=j; ++i,--j) res[i]=res[i]+res[j]-(res[j]=res[i]);//再次逆置回来方便去除后续0以及输出
i=strlen(res)-1;
while(res[i]=='0') res[i--]=0;
}
if(res[strlen(res)-1]=='.')res[strlen(res)-1]=0;
printf("%s\n",res);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj