POJ解题报告_1001_Exponentiation

题目描述

思路:

这道题是求高精度幂的结果,而不可能直接使用pow()函数,因为最后的结果太长了,需要使用数组来存储数据,所以必须改为使用大整数的运算,而这里主要算法是连续使用大整数乘法。大整数乘法核心算法如下:

c1[i+j]+=a[i]*b[j];
if (c1[i+j]>=10){
    c1[i+j+1]+=c1[i+j]/10;        
    c1[i+j]%=10;
}
其中a[i],b[i]为逆序的两个数,就是如果123×456,则a[]={3,2,1},b[]={654},当然结果也是逆序的,输出的时候需要转回来。这段代码其实是模拟真实的乘法运算,效率不高,而大整数乘法可以用分治法进行优化将时间复杂度由O(n^2)降低为O(nlogn)。

对于题目中小数点的处理,其实只需要将这个实数视为整数就行了,乘出来结果的小数点位置用类似科学计数法的处理就行了,比如123.456×789.123看做(123456×10^-3)×(789123×10^-3)=(123456×789123×10^-6),最后将小数点放在从后往左第6位就可以了,这个算法便是这道题的核心。

需要注意的是最后的输出,格式控制比较蛋疼,我错很多次就因为格式控制不正确。

代码:

#include <iostream>

using namespace std;

int main()
{
	int array[100]={0};
	char ch;
	int i=0,j=0,k=0;
	int deg,dotPos;
	int n,finaldotPos;
	char s[100];

	while (cin>>s>>n)
	{
		memset(array,0,sizeof(array));
		i=j=k=0;
		deg=dotPos=finaldotPos=0;
		while (i<strlen(s)){
			ch=s[i++];
			if(ch!='.')
				deg=i-1,array[j++]=atoi(&ch);
			else{
				dotPos=i-1;
				continue;
			}
		}

		if (dotPos==0){
			deg++;
			finaldotPos=0;
		}
		else
			finaldotPos=(deg-dotPos)*n;
		
		int c1[500]={0},temp[500];//存储乘法计算结果
		int r=0,len=deg;
		for (k=0;k<deg;++k)
			temp[k]=array[k];
		
		for (r=0;r<n-1;++r){//高精度幂计算,大整数乘法
			for (i=0;i<len;++i)
				for(j=0;j<deg;++j){
					c1[i+j]+=temp[len-1-i]*array[deg-1-j];
					if (c1[i+j]>=10){
						c1[i+j+1]+=c1[i+j]/10;
						c1[i+j]%=10;
					}
				}
				len+=deg;
				for (k=0;k<len;++k){
					temp[k]=c1[len-1-k];
					c1[len-1-k]=0;
				}
		}
		int intflag=0;
		for (k=0;k<len-finaldotPos;++k){
			if (temp[k]==0&&intflag==0)
				continue;
			else if(temp[k]!=0&&intflag==0){
				intflag=1;
				cout<<temp[k];
				continue;
			}
			
			if(intflag==1){
				cout<<temp[k];
			}
		}//输出整数部分
		
		
		int dotflag=0;
		int dottemp[100];
		int nonzeronum;
		i=0;
		for (k=len-1;k>=len-finaldotPos;--k){
			if (temp[k]==0&&dotflag==0)
				continue;
			else if (temp[k]!=0&&dotflag==0){
				dotflag=1;
				cout<<".";//输出小数点
				dottemp[i++]=temp[k];
				continue;
			}
			if (dotflag==1)
				dottemp[i++]=temp[k];
		}//清除小数部分最后的0
		
		nonzeronum=i;//输出小数部分
		for(i=nonzeronum-1;i>=0;--i)
			cout<<dottemp[i];
		cout<<endl;
	}

	return 0;
}

WA原因:
1.没有考虑到这种情况:输入10.00 2,应该输出100,而不是100.
2.最后输出结果之后没有cout<<endl,导致第二次输入数据时不能得出正确结果
3.没有考虑到最后计算结果精度,最开始声明的结果保存数组temp[100],最后改为temp[500],才保证了最后计算结果的准确性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值