PKU 1001 高精度乘幂

题目: 求Rn ,其中R是一个实数范围是 0.0 < R < 99.999 ,n是一个整数的范围是 0 < n <= 25.

分析:高精度运算,字串符模拟数值运算。需要注意的是各种输入格式处理:123, 0123, 012.3, 123., 123.0, 123.01, .123, .1230等等,我的方法是先把如上这些情况输入处理成(123,0),(123,0),(123,1),(123,0),(123,0),(12301,2),(123,3),(123,3)这些形式。即删除小数点,删除多余前面的0与后面的0存储,并且返回小数位数。整数乘幂运算过后再增加小数点处理。输出的时候注意1、整数不打印小数点 2、删除多余尾0  3、0.xxxx形式小数输出.xxxx

 

其中,字符串加、乘都写好相应子程序,子程序为了方便使用最好允许操作数与结果指向同一地址,即mul(result,op2,result)形式。

 

#include <iostream> #include <cstring> using namespace std; const int N = 8*25; void strRev(char *str){ int len = strlen(str); for(int i=0;i<len/2;i++){ char tmp=str[i]; str[i]=str[len-i-1]; str[len-i-1]=tmp; } } /*s1 is added by s2 and answer is stored in ans at last*/ void add(const char *s1, const char *s2, char *ans){ char op1[N], op2[N], sum[N]; strcpy(op1,s1); strcpy(op2,s2); int l1=strlen(op1); int l2=strlen(op2); int l= l1>l2 ? l1 : l2; strRev(op1); strRev(op2); int c = 0; for(int i=0;i<l;i++){ char e1 = l1>i ? op1[i]-'0' : 0; char e2 = l2>i ? op2[i]-'0' : 0; sum[i] = (e1 + e2 + c)%10 + '0'; c = (e1+e2+c)/10; } if(c==0) sum[l]='/0'; else strcpy(&sum[l],"1"); strRev(sum); strcpy(ans,sum); } /*op1 is multipled by char op2, answer is in result*/ void mul_string_char(const char *op1, char op2, char *result){ int c=0; int l = strlen(op1); for(int i=l-1;i>=0;i--){ result[i]=((op1[i]-'0')*(op2-'0')+c)%10+'0'; c=((op1[i]-'0')*(op2-'0')+c)/10; } if(c==0) result[l]='/0'; else{ for(int i=l-1;i>=0;i--) result[i+1]=result[i]; result[0]=c+'0'; result[l+1]='/0'; } } /*op1 is multiplied by string, answer is stored in result*/ void mul(char *s1, char *s2, char *ans) { char op1[N], op2[N], product[N], tmp[N]; strcpy(op1,s1); strcpy(op2,s2); product[0]='/0'; int l2=strlen(op2); for(int i=0;i<l2;i++){ int l=strlen(product);//make product = product*10 product[l]='0'; product[l+1]='/0'; mul_string_char(op1,op2[i],tmp); add(product,tmp,product); } strcpy(ans,product); } /*cut head zeros*/ void cutZero(char *str){ strRev(str); int l = strlen(str); for(int k=l-1;k>=0;k--) if(str[k]!='0'){ str[k+1]='/0'; break; } strRev(str); } /* deal with all kinds of input. * For example, input str: 123, 012.3, .123, 123., 123.0, 123.01, 123.010 * change them into (123,0), (123,1), (123,3), (123,0), (12301,2), (12301,2) * integer data is stored in str and return point bits */ int dealPoint(char *str){ int l=strlen(str); int i, j; for(i=0;i<l;i++) if(str[i]=='.') break; for(j=l-1;j>=0;j--) if(str[j]!='0'|| i >= j) break; if(i==l){//no point such as 123 cutZero(str); return 0; }else if(i==l-1 || i == j){//deal with cases such as 12., 12.0 str[i]='/0'; cutZero(str); return 0; }else{ str[j+1]='/0';//delete zeros behind j l = strlen(str);//delelte point for(int k=i+1;k<=l;k++) str[k-1]=str[k]; cutZero(str); return j-i; } } void dealPrint(char *result, int point){ int l=strlen(result), d; if(point==0) return; if(l>=point){ d = l-point; for(int i=l;i>=d;i--) result[i+1]=result[i]; result[d]='.'; }else{ d = point-l; for(int i=l;i>=0;i--) result[i+d+1]=result[i]; result[0]='.' ; for(int i=0;i<d;i++) result[i+1]='0'; } } int main() { int n, point; char s[N], ans[N]; while(cin>>s>>n){ if(n==0){ cout << 1 << endl; continue; } point = dealPoint(s); strcpy(ans,s); for(int i=0;i<n-1;i++){ mul(ans,s,ans); } dealPrint(ans,point*n); cout << ans << endl; } return 0; }

 

你可能感兴趣的:(PKU 1001 高精度乘幂)