OpenJudge1001Exponentiation
问题描述
Problems involving the computation of exact values of very large magnitude and precision are common. For example, the computation of the national debt is a taxing experience for many computer systems.
This problem requires that you write a program to compute the exact value of Rnwhere R is a real number ( 0.0 < R < 99.999 ) and n is an integer such that 0 < n <= 25.
要求
- 输入
- The input will consist of a set of pairs of values for R and n. The R value will occupy columns 1 through 6, and the n value will be in columns 8 and 9.
- 输出
- The output will consist of one line for each line of input giving the exact value of R^n. Leading zeros should be suppressed in the output. Insignificant trailing zeros must not be printed. Don't print the decimal point if the result is an integer.
-
思路
本题为高精度计算问题,需要将输入的字符串转换为数组,按照四则运算的方式进行运算,具体代码如下所示:
1 #include<iostream> 2 #include<string> 3 #include<string.h> 4 5 using namespace std; 6 7 struct bign{ 8 int data[1000]; 9 int length; 10 int point; 11 bign(){ 12 memset(data, 0, sizeof(data)); 13 length = 0; 14 point = 0; 15 } 16 }; 17 18 string str; 19 int n; 20 21 bign Change(){ 22 bign a; 23 a.point = str.length() - str.find('.') - 1; 24 int j = 0; 25 for(unsigned int i=0;i<str.length();i++){ 26 if(str[str.length() - i - 1]!='.'){ 27 a.data[j] = str[str.length() - i - 1] - '0'; 28 j++; 29 } 30 } 31 a.length = j; 32 return a; 33 } 34 35 bign multi(bign a, bign b){ 36 bign c; 37 int carry = 0; 38 for(int i=0;i<b.length;i++){ 39 c.length = i; 40 for(int j=0;j<a.length;j++){ 41 int temp = a.data[j] * b.data[i] + carry + c.data[i+j]; 42 c.data[c.length++] = temp % 10; 43 carry = temp / 10; 44 } 45 while(carry != 0){ 46 c.data[c.length++] = carry % 10; 47 carry /= 10; 48 } 49 } 50 c.point = a.point + b.point; 51 return c; 52 } 53 54 bign power(bign a, int n){ 55 if(n==0){ 56 bign d; 57 d.data[0] = 1; 58 d.length = 1; 59 return d; 60 } 61 if(n%2==1){ 62 return multi(a, power(a, n-1)); 63 } 64 else{ 65 return multi(power(a, n/2), power(a, n/2)); 66 } 67 } 68 69 void show(bign rs){ 70 string ans; 71 int zero = 0; //记录尾部0的数目 72 for(int i=0;i<rs.point;i++){ 73 if(rs.data[i]!=0){ 74 break; 75 } 76 else{ 77 zero++; 78 } 79 } 80 if(str[0]!='0'){ 81 for(int i=rs.length-1;i>=zero;i--){ 82 if(zero==rs.point){ 83 ans.insert(ans.end(), rs.data[i] + '0'); 84 } 85 else{ 86 if(i==rs.point){ 87 ans.insert(ans.end(), rs.data[i] + '0'); 88 ans.insert(ans.end(), '.'); 89 } 90 else{ 91 ans.insert(ans.end(), rs.data[i] + '0'); 92 } 93 } 94 } 95 } 96 else{ 97 ans.insert(ans.end(), '.'); 98 for(int i=rs.point-1;i>=zero;i--){ 99 ans.insert(ans.end(), rs.data[i] + '0'); 100 } 101 } 102 cout<<ans<<endl; 103 } 104 105 int main(){ 106 while(cin>>str>>n){ 107 bign bg = Change(); 108 bign rs = power(bg, n); 109 show(rs); 110 } 111 return 0; 112 }
在解题过程中,遇到的是尾部零处理和首部零处理问题,要注意的是,除了题中所给的样例,10.00之类的幂次需要考虑,这类测试数据,在尾部零处理中,不应该含小数点。