題目來源:http://poj.org/problem?id=1001&lang=zh-CN
求高精度冪 Time Limit: 500MS Memory Limit: 10000K Total Submissions: 160807 Accepted: 39157Description
對數值很大、精度很高的數進行高精度計算是一類十分常見的問題。比如,對國債進行計算就是屬於這類問題。Input
T輸入包括多組 R 和 n。 R 的值占第 1 到第 6 列,n 的值占第 8 和第 9 列。Output
對於每組輸入,要求輸出一行,該行包含精確的 R 的 n 次方。輸出需要去掉前導的 0 後不要的 0 。如果輸出是整數,不要輸出小數點。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.1268250301319697206612011 #include <iostream> 2 #include <string> 3 #include <vector> 4 5 using namespace std; 6 7 8 // Element == -1 ? reset 0 ! 9 inline void resetElement(int &ival) 10 { 11 if (ival == -1) 12 { 13 ival = 0; 14 } 15 } 16 17 // Element > 10 ? deal element! 18 inline void dealElement(vector<int> &ivec, vector<int>::size_type index) 19 { 20 while (ivec[index] >= 10) 21 { 22 int temp = ivec[index]; 23 ivec[index] %= 10; 24 index--; 25 resetElement(ivec[index]); 26 ivec[index] += (temp / 10); 27 } 28 } 29 30 // ivecR[index] * intR 31 void multiplicationCompute(vector<int> &ivecA, unsigned int &pointPosA, const int &intR, const int &pointPosR) 32 { 33 vector<int>::size_type currIndex = 0; 34 unsigned int val = 0; 35 36 for (vector<int>::size_type index = 0; index != ivecA.size(); ++index) 37 { 38 if (ivecA[index] != -1) 39 { 40 currIndex = index; 41 val = ivecA[index] * intR; 42 43 ivecA[index] = 0; // += 44 45 while (val) 46 { 47 resetElement(ivecA[currIndex]); 48 ivecA[currIndex] += (val % 10); 49 dealElement(ivecA, currIndex); 50 val /= 10; 51 currIndex--; 52 } 53 } 54 } 55 pointPosA = pointPosA + pointPosR; 56 } 57 58 59 int main(int argc, char *argv[]) 60 { 61 62 string strR; 63 unsigned int n; 64 65 while (cin >> strR >> n) 66 { 67 unsigned int intR = 0; 68 vector<int> ivecR; 69 vector<int> ivecA(200, -1); 70 unsigned int pointPositionR = 0; 71 unsigned int pointPositionA = 0; 72 73 74 //將R轉換為int型的vector,pointPositionR記錄小數點位置(其值代表小數位的位數) 75 for (string::size_type index = 0; index != strR.size(); ++index) 76 { 77 if (strR[index] != '.') 78 { 79 ivecR.push_back(strR[index] - '0'); 80 } 81 else 82 { 83 pointPositionR = strR.size() - 1 - index; 84 } 85 } 86 87 //將ivecR轉換成intR 88 for (vector<int>::size_type index = 0; index != ivecR.size(); ++index) 89 { 90 intR = intR *10 + ivecR[index]; 91 } 92 93 94 //將ivecR復制到ivecA,高位——低位存儲,pointPositionA = pointPositionR 95 for(int indexA = ivecA.size() - 1, indexR = ivecR.size() - 1; indexA >= 0 && indexR >= 0; --indexA, --indexR) 96 { 97 ivecA[indexA] = ivecR[indexR]; 98 } 99 pointPositionA = pointPositionR; 100 101 //if (n = 0) 102 //{ 103 // cout << 1 << endl; 104 // return 0; 105 //} 106 107 while (n >= 2) //若 n = 1, 則 ivecA就是結果 108 { 109 multiplicationCompute(ivecA, pointPositionA, intR, pointPositionR); 110 n--; 111 } 112 113 114 //純小數,小數位超過ivecA的實數位則補0 115 for (vector<int>::size_type index = ivecA.size() - 1; index >= ivecA.size() - pointPositionA; --index) 116 { 117 if (ivecA[index] == -1) 118 { 119 ivecA[index] = 0; 120 } 121 122 } 123 124 //後綴0處理 125 for (int index = ivecA.size() - 1; index >= 0 && ivecA[index] == 0; --index) 126 { 127 ivecA[index] = -1; 128 } 129 130 131 vector<int>::size_type indexBegin = 0; 132 while (indexBegin != ivecA.size() && ivecA[indexBegin] == -1) 133 { 134 indexBegin++; 135 } 136 137 if (indexBegin == ivecA.size()) 138 { 139 cout << 0 << endl; 140 } 141 else 142 { 143 for(vector<int>::size_type index = indexBegin; index != ivecA.size(); ++index) 144 { 145 if (ivecA[index] != -1) 146 { 147 if (index == ivecA.size() - pointPositionA) 148 { 149 cout << "."; 150 } 151 cout << ivecA[index]; 152 } 153 } 154 cout << endl; 155 } 156 } 157 return 0; 158 } View Code
求解思路:
1、使用數組存儲數據,保證數組的元素不大於9,不存儲小數點,通過一個整型變量記錄小數位的位數。用string接受輸入流的數據,再轉換成整型數組(不含“.”),作為第一次乘法計算的一個因子,並生成一個整數作為另一個因子。
2、核心函數是 void multiplicationCompute(vector<int> &ivecA, unsigned int &pointPosA, const int &intR, const int &pointPosR),計算數組存儲的大整數與底數的乘積。
為了方便計算,大整數存儲在數組的高位— —低位。計算的時候,從數組低位— —高位開始遍歷,每一位數組元素(非-1占位符)與底數相乘,並將結果依次存入數組。對於ivecA[index] 與底數的乘積,其個位存入index位,其更高位依次存入index--位。循環調用函數計算,其最終結果存儲在ivecA中。
3、輸出控制。整數不輸出小數點;小數位後綴0不輸出;純小數不輸出小數點前面的0;如果ivecA存儲的實數位小於小數位,則需要在前面補0。
不過很慚愧的是下面的代碼提交未能通過。在本機測試結果都正確,但是提交結果卻是wrong answer,一時半會也沒找到錯誤原因,待回頭再來看吧。