【PAT 甲级】A1103 Integer Factorization(30分)

【版本一:DFS递归版本,有一个测试点超时,27分】
虽然第一次尝试没有满分,但是超级无敌开心了!!第一次做PAT的压轴题,还好还好…

#include <bits/stdc++.h>
using namespace std;
int tmp[512];
int MAX=-1;
int ans[512];
bool flag=false;
void DFS(int index,int n,int k,int p)
{
	int sum=0;
	for(int i=0;i<k;i++)
	sum+=pow(tmp[i],p);
	if(index==k)	//boundary
	{
		if(sum==n)	//one possible answer
		{
			flag=true;
			int summ=0;
			for(int i=0;i<k;i++)
			summ+=tmp[i];
			if(summ>MAX)	//one possible answer
			{
				MAX=summ;	//update the value of MAXsum
				for(int i=0;i<k;i++)	//update the answer
				ans[i]=tmp[i];
			}
			else if(summ==MAX)	//further judge
			{
				bool fflag=false;	//initially, no update is assumed
				for(int i=0;i<k;i++)
				if(ans[i]>tmp[i])
				fflag=true;
				if(fflag)			//otherwise, update
				{
					for(int i=0;i<k;i++)
					ans[i]=tmp[i];
				}
			}
			else return;	//the answer is disregarded
		}
		return;		//this isn't the answer
	}
	sum-=pow(tmp[index],p);
	while(true)
	{	
		if((index==0) || (tmp[index]!=tmp[index-1]+1))
		{
			sum+=pow(tmp[index],p);
			if(sum<=n)
			{
				for(int i=index+1;i<k;i++)
				tmp[i]=1;
				DFS(index+1,n,k,p);
			}
			else
			{
				tmp[index]--;
				break;
			}
			sum-=pow(tmp[index],p);
			tmp[index]++;
		}
		else break;
	}
}
int main(void)
{
	int n,k,p;
	scanf("%d%d%d",&n,&k,&p);
	for(int i=0;i<k;i++)
	tmp[i]=1;
	DFS(0,n,k,p);
	if(flag)
	{
		printf("%d = ",n);
		for(int i=0;i<k;i++)
		{
			if(i!=k-1)
			printf("%d^%d + ",ans[i],p);
			else
			printf("%d^%d",ans[i],p);
		}
	}
	else
	{
		printf("Impossible");
	}
}

【版本二:增加剪枝条件(如果当前序列和小于可能解的序列和,则剪掉),并且为pow函数打表避免重复计算,25分】
雷!超时测试点2的时间压缩至7ms,但是测试点2竟然错误了,百思不得其解!!
在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
int tmp[512];
int MAX=-1;
int ans[512];
int power[21];
bool flag=false;
void DFS(int index,int n,int k)
{
	int sum=0,summ=0;
	for(int i=0;i<k;i++)
	{
		summ+=tmp[i];sum+=power[tmp[i]];
	}
	if(index==k)	//boundary
	{
		if(sum==n)	//one possible answer
		{
			flag=true;
			if(summ>MAX)	//one possible answer
			{
				MAX=summ;	//update the value of MAXsum
				for(int i=0;i<k;i++)	//update the answer
				ans[i]=tmp[i];
			}
			else if(summ==MAX)	//further judge
			{
				bool fflag=false;	//initially, no update is assumed
				for(int i=0;i<k;i++)
				if(ans[i]>tmp[i])
				fflag=true;
				if(fflag)			//otherwise, update
				{
					for(int i=0;i<k;i++)
					ans[i]=tmp[i];
				}
			}
			else return;	//the answer is disregarded
		}
		return;		//this isn't the answer
	}
	sum-=power[tmp[index]];
	summ-=tmp[index];
	while(true)
	{	
		if((index==0) || (tmp[index]!=tmp[index-1]+1))
		{
			sum+=power[tmp[index]];
			summ+=tmp[index];
			if(sum<=n && summ>=MAX)
			{
				for(int i=index+1;i<k;i++)
				tmp[i]=1;
				DFS(index+1,n,k);
			}
			else
			{
				tmp[index]--;
				break;
			}
			sum-=power[tmp[index]];
			summ-=tmp[index];
			tmp[index]++;
		}
		else break;
	}
}
int main(void)
{
	int n,k,p;
	scanf("%d%d%d",&n,&k,&p);
	for(int i=0;i<k;i++)
	tmp[i]=1;
	
	for(int i=0;i<=20;i++)
	{
		power[i]=pow(i,p);
	}
	
	DFS(0,n,k);
	if(flag)
	{
		printf("%d = ",n);
		for(int i=0;i<k;i++)
		{
			if(i!=k-1)
			printf("%d^%d + ",ans[i],p);
			else
			printf("%d^%d",ans[i],p);
		}
	}
	else
	{
		printf("Impossible");
	}
}

【版本三:把版本二的剪枝条件删掉,并且引入一个pow函数的表避免计算,并且DFS函数参数增加了sum一项,避免了每次DFS的一个O(k)级别的运算,30分】Accepted!第五个测试点通过时间为600ms,还可以接受。
在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
int tmp[512];
int MAX=-1;
int ans[512];
int power[20];
bool flag=false;
void DFS(int index,int n,int k,int sum)
{
	if(index==k)	//boundary
	{
		if(sum==n)	//one possible answer
		{
			flag=true;
			int summ=0;
			for(int i=0;i<k;i++)
			summ+=tmp[i];
			if(summ>MAX)	//one possible answer
			{
				MAX=summ;	//update the value of MAXsum
				for(int i=0;i<k;i++)	//update the answer
				ans[i]=tmp[i];
			}
			else if(summ==MAX)	//further judge
			{
				bool fflag=false;	//initially, no update is assumed
				for(int i=0;i<k;i++)
				if(ans[i]>tmp[i])
				fflag=true;
				if(fflag)			//otherwise, update
				{
					for(int i=0;i<k;i++)
					ans[i]=tmp[i];
				}
			}
			else return;	//the answer is disregarded
		}
		return;		//this isn't the answer
	}
	while(true)
	{	
		if((index==0) || (tmp[index]!=tmp[index-1]+1))
		{
			if(sum<=n)
			{
				for(int i=index+1;i<k;i++)
				tmp[i]=1;
				DFS(index+1,n,k,sum);
			}
			else break;
			sum-=power[tmp[index]];
			tmp[index]++;
			sum+=power[tmp[index]];
		}
		else break;
	}
}
int main(void)
{
	int n,k,p;
	scanf("%d%d%d",&n,&k,&p);
	for(int i=0;i<k;i++)
	tmp[i]=1;
	int s=0;
	while(true)
	{
		power[s]=pow(s,p);
		if(power[s]>400) break;
		s++;
	}
	
	DFS(0,n,k,k);
	if(flag)
	{
		printf("%d = ",n);
		for(int i=0;i<k;i++)
		{
			if(i!=k-1)
			printf("%d^%d + ",ans[i],p);
			else
			printf("%d^%d",ans[i],p);
		}
	}
	else
	{
		printf("Impossible");
	}
}
发布了15 篇原创文章 · 获赞 1 · 访问量 176

猜你喜欢

转载自blog.csdn.net/weixin_42278063/article/details/104580484