Sweety

Practice makes perfect

导航

Precision power (高精度幂运算)(相乘的变体)

Posted on 2014-09-21 17:14  蓝空  阅读(281)  评论(0编辑  收藏  举报

 

 

POJ 1001  http://poj.org/problem?id=1001

//注意存储方式是从后往前存储的 也就是逆序存储的
#include<iostream>
using namespace std;
char str[10];
int n, dot;
int res[200], a[200], b[200];//a记录的是相乘之后的数
int len, lena, lenb;//lena、lenb分别记录a,b的长度

void mul()
{
	int i,j;
	memset(res, 0, sizeof(res));
	for(i=1; i<=lena; i++)  
	{	
		for(j=1; j<=lenb; j++)
		{	
			res[i+j-1]=res[i+j-1]+a[i]*b[j];
			if (res[i+j-1]>9)
			{
				res[i+j] =res[i+j]+res[i+j-1]/10;
				res[i+j-1]%=10;
			}
		}
	}
	if (res[lena+lenb-1]>9) //最高位的处理 
	{		
		res[lena+lenb] = res[lena+lenb-1] / 10;    //res[lena+lenb] + 
		res[lena+lenb-1] = res[lena+lenb-1] % 10;
	}
	lena = lena + lenb;
	for (i=1; i<=lena; i++)   //将结果值重新放在a里
		a[i] = res[i];
}

int main()
{
	int i,j,up,down;
	while (scanf("%s %d", str, &n)!=EOF)
	{
		dot = -1;
		for (i=5, j=1; i>=0; i--)
		{
			if (str[i]!='.')
			{
				a[j]=b[j]=str[i]-'0';
			    j++;
			}
			else
				dot = i;
		}
		if(dot==-1)                 //如果没有小数,就有六位;否则,是五位
			lena=lenb=6;
		else
			lena=lenb=5;
		for (i=1; i<n; i++)
			mul();
		if (dot==-1)       //如果没有小数直接输出
		{
			for (i=lena; i>=1; i--)
				printf("%d", a[i]);
			printf("\n");
		}
		else//在此处处理小数的时候,对于那些在不计小数相乘后的结果前后有出现零的先处理零,将前后的零全部去掉,
			//然后再查看小数位置,调整输出的起始地址
		{
			dot=5-dot;//第几位是小数
			dot=dot*n;
			for (i=1; i<=lena; i++)//消除小数后的没有实际含义的零
			{
				if (a[i]!=0)
				{
					down=i;//记录小数后面第一个不为零的位置
					break;
				}
			}
			for (j=lena; j>=1; j--)//消除正式前的没有实际含义的零
			{
				if (a[j]!=0)
				{
					up = j;//记录整数后面第一个不为零的位置
					break;
				}
			}
			i=up;
			if (up<dot)//整数前需补零
				i = dot;
			j=down;
			if (j>dot)  //应对那些10.000这样
				j = dot + 1;
			for (; i>=j; i--)
			{
				if (i==dot)
					printf(".");
				printf("%d", a[i]);
			}
			printf("\n");
		}
	}
	return 0;
}