严格来说本解法不能算大数相乘的通用算法, 而只是针对题目中(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
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