严格来说本解法不能算大数相乘的通用算法, 而只是针对题目中(0.0 < R < 99.999)的trick. 因R位数很小, 所以本算法思路是把R扩大倍数而转成整数(99.999 -> 99999), 然后把每次乘积累加到结果数组中, 算法比较简单.
同时, 发现POJ本题的审核程序有bug. 题目要求对尾部(trailing)无效的0不能打印出来, 但实际审核时没有这么严谨, 可能是测试数据没有涵盖所有边界或者其它原因. 具体情况是: 对小于0的结果打印时不去掉尾部的0, 审核程序依然accepted. 举个例子, 对于小于1的R(如0.10000), 不论n取多少(如取3), 其乘方的结果是小于0的小数`.001000000000000`, 如果算法直接打印`.001000000000000`依然accepted, 但依题目的要求真正结果应是`.001`. 即把后文算法中如下注释掉的4行代码打开才是严格的, 但POJ的bug导致注释了也能accepted.
//while (product[j] == 0) // trim trailing zeros
//{
// j++;
//}
以下是题目与解法(C语言), 文末贴了参考来源
Exponentiation
Time Limit: 500MS | Memory Limit: 10000K | |
Total Submissions: 116340 | Accepted: 28271 |
Description
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
Output
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
#include <stdio.h>
#include <string.h>
int len; // total length of exponentiation result
int product[126] = {0}; // storing result, at most length 5*25 + 1 = 126
void multiply(int a[], int n)
{
int i;
int carry = 0; // a carry number in multiplying
for (i = 0; i < len; i++)
{
int temp = a[i]*n + carry;
a[i] = temp % 10;
carry = temp / 10;
}
while (carry)
{
a[i++] = carry % 10;
carry /= 10;
}
len = i;
}
int main(int argc, char* argv[])
{
int n; // power n
char s[6]; // real number R, at most the length is 6
while (scanf("%s %d", s, &n) != EOF)
{
int position=0, i=0, num=0, j=0;
for (i=0; i<strlen(s); i++)
{
if (s[i] == '.')
{
position = (strlen(s) - 1 - i) * n; // calculate decimal point position after R^n
}
else
{
num = num*10 + s[i] - 48; // transfer float to integer
}
}
// product calculation
product[0]=1;
len = 1;
for (i = 0; i < n; i++)
{
multiply(product, num);
}
// format output
if (len <= position) // product is less than 1
{
printf("."); // print decimal point
for (i=0; i<position-len; i++)
{
printf("0"); // print zero between decimal point and decimal
}
j = 0;
//while (product[j] == 0) // trim trailing zeros
//{
// j++;
//}
for (i=len-1; i>=j; i--)
{
printf("%d", product[i]);
}
}
else
{
j=0;
while (product[j]==0 && j<position) // trim trailing zeros
{
j++;
}
for (i=len-1; i>=j; i--)
{
if (i+1 == position) // cause index in C language starts from 0
{
printf(".");
}
printf("%d", product[i]);
}
}
printf("\n");
}
}
参考:
http://blog.csdn.net/xiongheqiang/article/details/7471661