Poj1001!高精度幂计算!【数学】

来源:互联网 发布:sql截断特定字符 编辑:程序博客网 时间:2024/06/06 03:42

看了别人的代码才写出来...附上链接http://blog.csdn.net/alongela/article/details/6788237

用c语言做简直就是虐心啊!!!!!!!!

/*ExponentiationTime Limit: 500MS  Memory Limit: 10000K Total Submissions: 133938  Accepted: 32757 DescriptionProblems 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 Rn where R is a real number ( 0.0 < R < 99.999 ) and n is an integer such that 0 < n <= 25. InputThe 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.OutputThe 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.Sample Input95.123 120.4321 205.1234 156.7592  998.999 101.0100 12Sample Output548815620517731830194541.899025343415715973535967221869852721.0000000514855464107695612199451127676715483848176020072635120383542976301346240143992025569.92857370126648804114665499331870370751166629547672049395302429448126.76412102161816443020690903717327667290429072743629540498.1075960194566517745610440100011.126825030131969720661201HintIf you don't know how to determine wheather encounted the end of input: s is a string and n is an integer C++while(cin>>s>>n){...}cwhile(scanf("%s%d",s,&n)==2) //to  see if the scanf read in as many items as you want/*while(scanf(%s%d",s,&n)!=EOF) //this also work    {...}SourceEast Central North America 1988*//*此题第一步就是处理输入的数A中的小数点,先把小数点去掉,把原来的数存储在一个整型数组中,记录小数点的位置,然后再开一个整型数组存储中间结果。接下来比较简单,设数组1和数组2一开始存储A,数组3是中间数组,每次由数组3来保存数组1和数组2的相乘结果,然后把数组3复制到数组1,由于N最大只是25,因此这种方法还是可以的。得出结果后就是计算小数点的位置,这个由原来的位置乘以N就可以了,不过要注意运算过程数组刚好是反向的,因此也要小小的处理一下。确定小数点的位置之后还要去掉前导0和后导0,这个可以通过确定起始位和终止位来输出数组1中保存的结果,POJ的讨论里面有一些测试数据,有一些比较绝,对发现错误很有帮助,比如10.000 1这个输入的输出应该为10。*/
//此题有个关键在于两个数相乘,可以忽略前导0和后缀0,直接拿五位相乘不会影响到计算结果#include<stdio.h>#include<string.h>int a[500], b[500],  c[500], lc, lb, la;char s[10];void mul(){int i, j;memset(b, 0, sizeof(b));for(i = 1; i<= la; i++){for(j = 1; j <= lc; j++){b[i+j-1] += a[i] * c[j];if(b[i+j-1] > 9){b[i+j] += b[i+j-1] / 10;b[i+j-1] %= 10;}}}lc = lc + la;for(i = 1; i <= lc;i++)c[i] = b[i];}int main(){ int n, dot, i, j; while(scanf("%s %d", s, &n) != EOF) {dot = -1;j = 1;for(i = 5; i >= 0; i--){if(s[i] != '.')a[j] = c[j++] = s[i] - 48;elsedot = i;}if(dot == -1) lc = la = 6;//如果没有小数点elselc = la = 5;//否则就将其当作是五位数for(i = 1; i < n; i++)//n次相乘mul();if(dot == -1){for( i = lc; i >= 0; i--)printf("%d", c[i]);printf("\n");}else{dot = n*(5-dot);//小数点的位置int fir, las; for(i = lc; i > 0; i--) if(c[i] != 0)//找出最高位 { fir = i; break;} for(j = 1; j <= lc; j++)//找出最低位 if(c[j] != 0)  {las = j;break;}i = fir; if(fir < dot) i =dot;//如果答案是个纯小数 j = las; if( las > dot) j = dot+1;//如果答案是个纯整数 for(; i >= j; i--) {if(i == dot)printf(".");printf("%d", c[i]);}printf("\n");}}return 0;}//以下均为本人的错误代码...../*#include<stdio.h>#include<string.h>int main(){    char s[6];    int i, j, k, n, m , a[6], b[200], point, c[200];    while(scanf("%s %d", s, &n ) != EOF)    {m = 0;point = 0;    for(i = 0; i < 6; i++)    {if(s[i] != '0' && s[i] != '.'){for(j = 5; j >= i; j--){if( s[j] != '0' ){point = j;if(s[j] == '.') j--;for( k = i; k <= j; k++){if(s[k] == '.') continue;a[m++] = s[k] - 48;break;}}break;}}for(i = 0; i < 6; i++)if(s[i] == '.') {point = point - i;break;}int segb = 1, t;memset(b, 0, sizeof(b));memset(c, 0, sizeof(c));b[0] = 1;for(i = 0; i < m/2; i++){t = a[i] ;a[i] = a[m-1-i];a[m-1-i] = t;}for(i = 0; i < n; i++){for(j = 0; j < m; j++){for(k = 0; k <segb; k++)c[k+j] += b[k] * a[j];}segb += m - 1;for(t = 0; t < segb; t++)if(c[t] > 9){c[t+1] += c[t] / 10;c[t] %= 10;}if(c[segb] > 0)segb++;for(j = 0; j < segb; j++)b[j] = c[j];memset(c, 0, sizeof(c));}//printfif(point < 0){for(i = 0; i < segb; i++)printf("%d", b[i]);printf("\n");}else{point  *= n;if(point >= segb){printf(".");for(i = 0; i < point; i++){if( i > segb) printf("0");else{for(j = 0; j < segb ; j++){if(b[j] != 0){for(k = j; k < segb; k++)printf("%d", b[segb-1-j])*//*int a[7], b[200], point;int main(){    int i, j, n, m,k;    char s[7];    while(scanf("%s %d", s, &n) != EOF)    {j = 0;point = 0;memset(b, 0, sizeof(b));if(s[0] == '0'){for(i = 2; i < 6; i++)if(s[i] != '0'){for(m = 5; m >= i; m--)if(s[m] != '0'){for(k = i; k <= m; k++)a[j++] = s[k] - 48;point = m-1;break;}break;}}else {if( strchr(s, '.') ){for(m = 5; m > 0; m--)if(s[m] != '0'){for(k = 0;k <= m; k++)if(s[k] != '.')a[j++] = s[k] - 48;else point  = m - k;break;}}else{for(i = 0; i < 6; i++)a[j++] = s[i] - 48;}}m  = j;point *= n;int t, segb, y;for(i  = 0; i < m/2; i++){t = a[i];a[i] = a[m-1 - i];a[m-i-i]  = t;}for(i = 0; i < m; i++){b[i] = a[i];printf("%d", b[i]);}printf("\n");segb = m;for( i = 1; i < n;i++)//n次方 {for(j = 0; j < m; j++ )//a{y = j;for(k = 0; k < segb; k++)//bb[y++] += b[k] * a[j];}for(t = 0; t <  y ; t++)//进位 if(b[t] > 9){b[t+1] += b[t] /10;b[t] %= 10;}segb = y;}if(point == 0){for(i = segb-1; i >= 0; i--)printf("%d", b[i]);printf("\n");}else{if( point < segb){for(i = segb-1; i >= 0; i--)if( i == segb - 1 - point)printf("%d.",b[i]);elseprintf("%d", b[i]);printf("\n");}else{printf(".");for(i = point;i >= 0; i--) {if(point > segb-1)printf("0");elseprintf("b[i]");}printf("\n");}}}return 0;}*/


 题意:给出一个浮点数r长度为6位,和一个整数n<=25,求r^n,输出忽略前导0和后导0。

思路:首先我们要将小数点忽略点,简单的做大数相乘的算法,然后我们只要算出小数点的位置并插入即可,最后输出忽略前面的0和后面的0即可。

难点:要想到将大数乘法长度相加的往上乘,即假设n位的乘上n位得到的数字为2n位(其实并没有这么多位),这个是为了方便最后小数点找位置而设计的。其次就是特殊考虑纯小数和纯整数的情况。

0 0
原创粉丝点击