天天看點

HDU-1063 高精度實數乘法

我需要逐漸提高自己實作代碼的能力。

93ms,希望知道更快的解法。

/*
 * hdu-1063 exponantaion
 * mike-w
 * 2012-5-24
 */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAX_NUM_LEN 150
#define min(a,b) ((a)<(b)?(a):(b))
#define NMIKE_DEBUG

typedef struct long_double
{
	int s[MAX_NUM_LEN];
	int dot; 
	int start;
}ld;

int disp(ld *a)
{
	int end,i,j;
	/* whole part */
	end=MAX_NUM_LEN - a->dot;
	for(i=0;i<MAX_NUM_LEN && a->s[i]==0;i++)
		;
	if(i<end)
	{
		for(;i<end;i++)
			printf("%d",a->s[i]);
	}
	else if(!a->dot)
		putchar('0');
	if(a->dot)
		putchar('.');
	/* small part */
	for(i=MAX_NUM_LEN-1;i>=0 && a->s[i]==0;i--)
		;
	if(i>=end)
		for(j=end;j<=i;j++)
			printf("%d",a->s[j]);
	putchar('\n');
	return 0;
}

int read_num(ld *a)
{
	memset(a,0,sizeof(ld));
	char buf[MAX_NUM_LEN];
	if(scanf("%s",buf)==EOF)
		return -1;
	int len=strlen(buf);
	int dot=0,i,p;
	for(i=len-1;i>=0 && buf[i]!='.';i--)
		;
	dot=len-i-1;
	if(dot==len)
		dot=0;
	a->dot=dot;
	for(i=1,p=1;i<=len;i++)
		if(buf[len-i]!='.')
			a->s[MAX_NUM_LEN-p]=buf[len-i]-'0',p++;
	for(i=0;i<MAX_NUM_LEN;i++)
		if(a->s[i])
			break;
	if(i==MAX_NUM_LEN)
		a->start=MAX_NUM_LEN-1;
	else
		a->start=i;
	return 0;
}

int simp(ld *a)
{
	if(a->dot==0)
		return -1;
	int i,len;
	for(i=MAX_NUM_LEN-1;i>=0 && a->s[i]==0;i--)
		;
	len=MAX_NUM_LEN-i-1;
	len=min(len,a->dot);
	for(i=MAX_NUM_LEN-1;i-len>=0;i--)
		a->s[i]=a->s[i-len];
	for(;i>=0;i--)
		a->s[i]=0;
	a->dot-=len;
	return 0;
}

int mul(ld *a1, ld *a2, ld *ans)
{
	int i,j,carry;
	memset(ans,0,sizeof(ld));
	for(i=1; a1->start-2 <= MAX_NUM_LEN-i; i++)
		for(j=1,carry=0; MAX_NUM_LEN-j>=a2->start-2 && MAX_NUM_LEN-j-i+1>=0; j++)
		{
			ans->s[MAX_NUM_LEN-j-i+1]+=
				a1->s[MAX_NUM_LEN-i]*a2->s[MAX_NUM_LEN-j]+carry;
			carry=ans->s[MAX_NUM_LEN-j-i+1]/10;
			ans->s[MAX_NUM_LEN-j-i+1]%=10;
		}
	ans->dot=a1->dot+a2->dot;
	for(i=0;i<MAX_NUM_LEN-1;i++)
		if(ans->s[i])
			break;
	if(i==MAX_NUM_LEN)
		ans->start=MAX_NUM_LEN-1;
	else
		ans->start=i;
	return 0;
}

int main(void)
{
#ifndef ONLINE_JUDGE
	freopen("exp.in","r",stdin);
#endif
	ld a1,a2,a3;
	int e;
	while(read_num(&a1)!=-1)
	{
		scanf("%d",&e);
#ifdef MIKE_DEBUG
		disp(&a1);
#endif
		if(e==0)
		{
			puts("1");
			continue;
		}
		simp(&a1);
		memset(&a2,0,sizeof(a2));
		a2.s[MAX_NUM_LEN-1]=1;
		while(e-->0)
		{
			mul(&a1,&a2,&a3);
			memcpy(&a2,&a3,sizeof(ld));
			simp(&a2);
		}
		disp(&a3);
	}
	return 0;
}
           

繼續閱讀