求幂

来源:互联网 发布:支付宝没开网络被盗刷? 编辑:程序博客网 时间:2024/06/06 01:11

求幂

时间限制(普通/Java):1000MS/3000MS          运行内存限制:65536KByte
总提交:390            测试通过:98

描述

Rn次幂(0.0<r<99.999,0<n<=25)

输入

每行输入两个数Rn

R值占1-6列,n8-9

输出

对应于每一行输入,输出Rn次幂

前导的0不要输出

无意义的0不要输出

如果结果是一个整数,不要输出小数点

最后一行是空行

样例输入

95.123 12
0.4321 20
5.1234 15
6.7592  9
98.999 10
1.0100 12

样例输出

548815620517731830194541.899025343415715973535967221869852721
.00000005148554641076956121994511276767154838481760200726351203835429763013462401
43992025569.928573701266488041146654993318703707511666295476720493953024
29448126.764121021618164430206909037173276672
90429072743629540498.107596019456651774561044010001
1.126825030131969720661201

题目来源

POJ


分析:

大数运算,涉及小数点和0的问题,有些复杂。

老方法输入字符串转化成int型数组,这里r是6位的,n不重要,因为空格结束,所以用循环

while(scanf("%s %d",&s,&n) != EOF) 
将6位的char型数组转换成int型数组,注意:数组开6位出错,因为还有一个结束符,索性直接开10。为了输出考虑,记录小数点后面的数的个数point。

考虑到大数相乘时数组下标从0开始,将int型数组逆序。

之后大数相乘,将int数组a拷贝到int数组b,方便传递参数。(写法有很多,感觉写的好烦)num为一开始输入的字符串里数字的个数,不包括0.0001中前面无意义的0,每次乘以b数组,数组的个数num <= num+6,因为b数组长度小于6 。

大数相乘:

void fun(int a[], int b[], int num){int mul[10000] = {0};for(int i=0;i<num;i++)for(int j=0;j<5;j++)mul[i+j] += a[i] * b[j];for(int i=0;i<num+6;i++) // +6 足矣{mul[i+1] += mul[i] / 10;mul[i] = mul[i] % 10;}for(int i=0;i<num+6;i++) // 再赋予aa[i] = mul[i];}
每次乘完一个b数组,将得到的乘积数组再返回给a,循环n-1次。最后得到的最终数组是逆序的,且前后有一些无效的0。

Eg:95.123 12 得到的为:12725896912276............................651884500000000000

要输出的是:548815620517731830194541.899025343415715973535967221869852721

只要输入的小数点后面不是1.1100这种情况,首位一定非0。


最重要的是输出。

小数点后的位数为point*n,还有一种特殊情况:小数点后位数中有无效的0。原因是1.1100记录的point为4,则point*n=4n,但是其实只要输出2n,因为后面的0无效。

for(i=num-1;i>=0;i--) if(a[i]!=0) break;
此时i为总的数字的位数。

if(point>i) // .xxxxx{printf("."); // 全在小数点右边//for(tmp=0;tmp<num;tmp++) // 右边多余的0不输出if(a[tmp]!=0) break;//for(int k=point-1;k>=tmp;k--) // 逆序输出{printf("%d",a[k]);}}
else // xxxx.xxxx 或者 xxxx{for(;i>point-1;i--) // 打印小数点左边的数 条件 i>point-1 保证小数point个{printf("%d",a[i]);}//for(tmp=0;tmp<num;tmp++) // 小数点右边第一个非0的下标 tmpif(a[tmp]!=0) break;//if(i>=tmp) // 存在小数printf(".");            for(;i>=tmp;i--)printf("%d",a[i]);}

完整代码:

#include<stdio.h>//求幂void fun(int a[], int b[], int num){int mul[10000] = {0};for(int i=0;i<num;i++)for(int j=0;j<5;j++)mul[i+j] += a[i] * b[j];for(int i=0;i<num+6;i++) // +6 足矣{mul[i+1] += mul[i] / 10;mul[i] = mul[i] % 10;}for(int i=0;i<num+6;i++) // 再赋予aa[i] = mul[i];}int main(){char s[10];int n;while(scanf("%s %d",&s,&n) != EOF) //while(cin>>s>>n){int a[10000] = {0};int num= 0,point;for(int i=0;i<6;i++){if(num == 0 && s[i] == '0') // 首位为0{continue;}if(s[i] != '.')a[num ++] = s[i] - '0';  // m.数字 != 0if(s[i] == '.')point = 5 - i; // 小数点后面几位 1.0100 }//逆序for(int i=0;i<num/2;i++){int tmp = a[i];a[i] = a[num - i - 1];a[num -i -1] = tmp;}//start!//拷贝数组a到数组b,作乘数int b[5];for(int i=0;i<5;i++)b[i] = a[i];                //循环求幂for(int i=0;i<n-1;i++){fun(a, b, num);num = num + 6;}//输出重点! 依据小数点后数的个数point = point * n; // 小数点后面几位int i,tmp;for(i=num-1;i>=0;i--) // num-1 ~ 0; 第一个非0的是先输出的(1.23456 中的1)if(a[i]!=0) break;if(point>i) // .xxxxx{printf(".");//for(tmp=0;tmp<num;tmp++)if(a[tmp]!=0) break;//for(int k=point-1;k>=tmp;k--) // 逆序输出{printf("%d",a[k]);}}else // xxxx.xxxx or xxxx{for(;i>point-1;i--) // 打印小数点左边的数 条件 i>point-1 保证小数point个{printf("%d",a[i]);}//for(tmp=0;tmp<num;tmp++) // 多余的0无需输出if(a[tmp]!=0) break;//if(i>=tmp) // 存在小数printf(".");            for(;i>=tmp;i--)printf("%d",a[i]);}printf("\n");}return 0;}








0 0
原创粉丝点击