PKU--1001(hdu 1063)---[Exponentiation] 字符串模拟

解题思路:

 

针对数据的特点n<=25普通的大数乘法即可,算法不难,主要是输入的处理有点复杂,很容易漏掉!
WA的请注意。输入数据需要考虑R和n的特殊情况!

分情况讨论:R:1,整数2,小数
然后对于每一种情况又分有无前导零,后导零。
R:000000 000100
R:小数点可以在任意位置如:.00000 000.00 00000.
n注意为0的情况!

 

 

优化前代码:在PKU能过,在杭电TLE,郁闷了下(杭电上还是有很多变态数据的....)

 

优化前代码:

POJ Accepted 168K 16MS C++ 1692B
HDU Time Limit Exceeded 1063 500MS 220K 1748 B

 

 

CODE(1):优化前

#include <iostream>
#include <string.h>
#define N 200
int in[N],out[N],temp[N];
char ans[N];
void A(char *s)
{
	int len = strlen(s);
    char *p = s + len - 1;
    if (strchr(s, '.'))
		while (!(*p>='1'&&*p<='9')&&*p!='.') *p-- = '/0';//让*p='/0',然后p--;
		if (*p == '.') *p = '/0';
}
void multiply(int a[N],int b[N],int c[N])
{
	int i,j,w=0,v=0;
	for(i=0;i<N;i++)//初始化
		c[i]=0;
	for(i=0;i<N;i++)
		for(j=0;j<N;j++)
			c[i+j]+=a[i]*b[j];//很巧妙
		for(i=0;i<N-1;i++)//进位处理
		{
			c[i+1]+=c[i]/10;
			c[i]%=10;
		}
}
int main ()
{
	char *pa,a[20];
	int i,b,k,j;
	while(scanf("%s %d",a,&b)!=EOF)
	{
		memset(in,0,sizeof(in));
		memset(temp,0,sizeof(temp));
		memset(out,0,sizeof(out));
		memset(ans,'/0',sizeof(ans));
		if(b==0)
		{printf("1/n");continue;}
		int flag=-12,flag1=0;//标记输入的是否是整数
		for(k=0,i=strlen(a)-1;i>=0;i--)
		{
			if(a[i]=='.')
				flag=strlen(a)-i-1;//记录小数点位子,即小数点后有几位
			else
				in[k++]=a[i]-'0';
		}
		for(i=0;i<k;i++)
			temp[i]=out[i]=in[i];
		int tt=k-1;
		while(out[tt]==0&&tt>=0) tt--;//n==1时去前导0
		if(tt<0)
		{printf("0/n");flag1=1;continue;}
		int T=b-1;//要乘的次数
		while(T--)
		{
			multiply(in,temp,out);
			memcpy(temp,out,N*sizeof(int));
		}
		//int pos=flag*b;
		if(flag==-12)//输入为整数的情况
		{
			i=N-1;
			while(!temp[i]) i--;
			if(i<0)
				printf("0");
			for(;i>=0;i--)
				printf("%d",temp[i]);
			printf("/n");
		}
		else
		{
			int pos=flag*b;
			for(i=0,j=N-1;i<N;i++,j--)
			{
				if(i<pos)
					ans[j]=out[i]+'0';
				else if(i==pos)
					ans[j]='.';
				else
					ans[j]=out[i-1]+'0';
			}
			pa=ans;
			A(pa);
			while(*pa=='0') pa++;
			puts(pa);
		}
	}
	return 0;
}

 

 

 

优化后代码:

OPJ  Accepted 168K 0MS C++ 1759B
HDU  Accepted 1063 46MS 248K 1898 B C++

 

 CODE(2):优化后

#include <iostream>
#include <string.h>
#define N 160
int in[N],out[N],temp[N];
char ans[N];
void A(char *s)//小数点后零的处理
{
	int len = strlen(s);
    char *p = s + len - 1;
    if (strchr(s, '.'))
		while (!(*p>='1'&&*p<='9')&&*p!='.') *p-- = '/0';//让*p='/0',然后p--;
		if (*p == '.') *p = '/0';
}
void multiply(int a[N],int b[N],int c[N])//大数乘法
{
	int i,j,w=0,v=0,m,n;
	for(i=0;i<N;i++)//初始化
		c[i]=0;
	m=n=N-1;//进行时间上的优化
	while(!a[m]&&m>0) m--;
	while(!b[n]&&n>0) n--;
	for(i=0;i<=m;i++)
		for(j=0;j<=n;j++)
			c[i+j]+=a[i]*b[j];//很巧妙
		for(i=0;i<N-1;i++)//进位处理
		{
			c[i+1]+=c[i]/10;
			c[i]%=10;
		}
}
int main ()
{
	char *pa,a[20];
	int i,b,k,j;
	while(scanf("%s %d",a,&b)!=EOF)
	{
		memset(in,0,sizeof(in));//初始化
		memset(temp,0,sizeof(temp));
		memset(out,0,sizeof(out));
		memset(ans,'/0',sizeof(ans));
		if(b==0)//b==0时的特殊处理
		{printf("1/n");continue;}
		int flag=-12;//标记输入的是否是整数
		for(k=0,i=strlen(a)-1;i>=0;i--)
		{
			if(a[i]=='.')
				flag=strlen(a)-i-1;//记录小数点位子,即小数点后有几位
			else
				in[k++]=a[i]-'0';
		}
		for(i=0;i<k;i++)
			temp[i]=out[i]=in[i];
		int tt=k-1;
		while(out[tt]==0&&tt>=0) tt--;//n==1时去前导0
		if(tt<0)
		{printf("0/n");continue;}
		int T=b-1;//要乘的次数
		while(T--)
		{
			multiply(in,temp,out);
			memcpy(temp,out,N*sizeof(int));//将out复制给temp
		}
		//int pos=flag*b;
		if(flag==-12)//输入为整数的情况
		{
			i=N-1;
			while(!temp[i]) i--;
			if(i<0)
				printf("0");
			for(;i>=0;i--)
				printf("%d",temp[i]);
			printf("/n");
		}
		else//小数情况
		{
			int pos=flag*b;
			for(i=0,j=N-1;i<N;i++,j--)
			{
				if(i<pos)
					ans[j]=out[i]+'0';
				else if(i==pos)
					ans[j]='.';
				else
					ans[j]=out[i-1]+'0';
			}
			pa=ans;
			A(pa);
			while(*pa=='0') pa++;
			puts(pa);
		}
	}
	return 0;
}

/*

附录,别人的一些数据:
95.123 12
0.4321 20
5.1234 15
6.7592 9
98.999 10
1.0100 12
.00001 1
.12345 1
0001.1 1
1.1000 1
10.000 1
000.10 1
000000 1
000.00 1
.00000 0
000010 1
000.10 1
0000.1 1
00.111 1
0.0001 1
0.0001 3
0.0010 1
0.0010 3
0.0100 1
0.0100 3
0.1000 1
0.1000 3
1.0000 1
1.0000 3
1.0001 1
1.0001 3
1.0010 1
1.0010 3
1.0100 1
1.0100 3
1.1000 1
1.1000 3
10.000 1
10.000 3
10.001 1
10.001 3
10.010 1
10.010 3
10.100 1
10.100 3
99.000 1
99.000 3
99.001 1
99.001 3
99.010 1
99.010 3
99.100 1
99.100 3
99.998 1
99.998 3
*/

你可能感兴趣的:(c,算法,优化,ini)