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

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

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

/*Exponentiation
Time Limit: 500MS  Memory Limit: 10000K 
Total Submissions: 133938  Accepted: 32757 

Description

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 Rn where R is a real number ( 0.0 < R < 99.999 ) and n is an integer
 such that 0 < n <= 25. 
Input

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.
Output

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.
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.126825030131969720661201
Hint

If 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)
{
...
}
c
while(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    
{
...
}
Source

East 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;
				else
				dot = i;
			}
			if(dot == -1) lc = la = 6;//如果没有小数点
			else
			lc = 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));
		}
		//printf
		if(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++)//b
					b[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]);
				else
				printf("%d", b[i]);
				printf("\n");
			}
			else
			{
				printf(".");
				for(i = point;i >= 0; i--) 
				{
					if(point > segb-1)
					printf("0");
					else
					printf("b[i]");
				}
				printf("\n");
			}
		}
	}
	return 0;
}
*/


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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值