POJ 1001 解题报告
2011-09-03 14:37
447 查看
这道题主要是考察数的高精度乘法,使用数组存储数据,数组中的元素对于高精度数据中的某一位。我用的思想很简单,类似我们手算乘法时采用的步骤,这是在两层的for()循环中实现的。需要注意一个问题,如果采用unsigned char型存储元素,在运算的过程中Rslt[]元素的中间结果可能超过255,造成乘法结果的中间部分数据不正确。因此,Rslt[]进行累加时,需要及时进位。在我的程序中,对数据有效位前后有0的情况做了处理,避免乘法过程中出现过多不必要的运算。但这也导致刚开始对10.0000这样的数据处理出现错误,后来用dotPos的正负表示小数点的位置,解决了此问题。
另外,对于高阶次幂,减少乘法使用的次数,采用降幂的思想。如2^9,可以看成(4^4)*2,进一步(16^2)*2。但是如何实现?这里,可以根据幂的二进制形式进行处理,如9表示成1001, 25表示成11001。具体见代码。注释部分采用这种思想,在VC运行通过。由于gcc没有对itoa实现,故submit的时候还用的传统方法。
另外,对于高阶次幂,减少乘法使用的次数,采用降幂的思想。如2^9,可以看成(4^4)*2,进一步(16^2)*2。但是如何实现?这里,可以根据幂的二进制形式进行处理,如9表示成1001, 25表示成11001。具体见代码。注释部分采用这种思想,在VC运行通过。由于gcc没有对itoa实现,故submit的时候还用的传统方法。
#include <stdio.h> /*#include <stdlib.h> */ #include <string.h> unsigned char Rslt[200] = {0}; int do_multiple(unsigned char *MultiA, unsigned char *MultiB, int lenA, int lenB) { int i, j, k; memset(Rslt, 0, sizeof(Rslt)); for(i = 0; i < lenA; i++) { for(j = 0; j < lenB; j++) { Rslt[i+j] += MultiA[i]*MultiB[j]; Rslt[i+j+1] += Rslt[i+j]/10; Rslt[i+j] %= 10; } } for(k = lenA+lenB-1; Rslt[k] == '\0'; k--){} return (k+1); } int main(void) { int Power, dotPos; int num_len, rslt_len; /* char Power_buf[5]; */ char Num[10]; unsigned char ReverseNum[6]; unsigned char temp_rslt[200] = {0}; int i, j; while(scanf("%s %d", Num, &Power) == 2) { /* itoa(Power, Power_buf, 2); */ dotPos = 0; for(i = 0; Num[i] != '\0'; i++) { if(Num[i] != '.') Num[i - (dotPos != 0)] = Num[i]; else dotPos = i; } i -= (dotPos != 0); for(--i; (Num[i] == '0'); i--){} Num[i+1] = '\0'; num_len = strlen(Num); dotPos = num_len - dotPos; for(j = 0; i >= 0; i--) { ReverseNum[j++] = Num[i]-'0'; } memcpy(Rslt, ReverseNum, num_len); rslt_len = num_len; for(i = 1; i < Power; i++) { memcpy(temp_rslt, Rslt, rslt_len); rslt_len = do_multiple(temp_rslt, ReverseNum, rslt_len, num_len); } /* for(i = 1; i < (signed)strlen(Power_buf); i++) { memcpy(temp_rslt, Rslt, rslt_len); rslt_len = do_multiple(temp_rslt, temp_rslt, rslt_len, rslt_len); if(Power_buf[i] == '1') { memcpy(temp_rslt, Rslt, rslt_len); rslt_len = do_multiple(temp_rslt, ReverseNum, rslt_len, num_len); } } */ dotPos *= Power; if(dotPos >= rslt_len) { putchar('.'); for(i = dotPos; i > rslt_len; i--) putchar('0'); } for(i = rslt_len; i > 0; i--) { if(dotPos == i) putchar('.'); putchar(Rslt[i-1]+'0'); } while(dotPos++ < 0) putchar('0'); putchar('\n'); } return 0; }
相关文章推荐
- POJ1001 Exponentiation (解题报告)
- POJ 1001 解题报告 高精度大整数乘法模版
- POJ 1001 解题报告
- POJ 1001 解题报告 高精度大整数乘法模版
- poj1001解题报告
- POJ 1001 Exponentiation [解题报告] Java
- POJ 1001 解题报告
- poj1001 解题报告
- POJ解题报告_1001_Exponentiation
- POJ 1001 解题报告 Exponentiation
- [POJ 1001] Exponentiation C++解题报告 JAVA解题报告
- poj1001解题报告+测试数据
- POJ 1001(浮点数高精度幂) 解题报告
- POJ1001 Exponentiation解题报告
- POJ 1001 Exponentiation C++解题报告 JAVA解题报告
- POJ 1001 Exponentiation解题报告
- POJ 1001(浮点数高精度幂) 解题报告
- POJ 1001 Exponentiation解题报告
- POJ1001 解题报告
- poj&nbsp;1001&nbsp;解题报告