1103 Integer Factorization (30分) 测试点2 测试点5

我是从大数字往小数字去枚举的,在dfs函数中先做不选择该数,然后再选择该数就过不了测试点2。如果想要过测试点2的话改变这两句话的顺序即可。

测试数据可以用100 5 2去跑一下。

至于为什么会这样解释如下:

如果不选择该数在前结果是: 100 = 5^2 + 5^2 + 5^2 + 4^2 + 3^2

如果选择该数在前结果是:100 = 6^2 + 4^2 + 4^2 + 4^2 + 4^2

原因就是如果你的代码是不选择这个数的代码在前的话就会导致你深度优先一直到从10~6都不选择,然后你选择5后你得到5 5 5 4 2的结果,此时和已经是最大22了,虽然你继续运行这个程序依然能得到6 4 4 4 4这个中间结果但是因为和是相等所以程序不会保存。如果想要消除这个影响的话你就需要在底数和相等时再进行判断,这样的话显然会大大增加程序的运行时间。

测试点5的问题:只要在dfs外计算底数的P次方的结果然后在dfs时直接用这个结果就能通过测试点5了,不要在dfs过程中去计算底数的P次方。

ps:其实你多点几次提交碰到一个好点服务器测试点5也能过。

无法通过测试点2的代码:

#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
int N,K,P;
vector<int> v,tmp,ans;
int maxSum = -1;
void dfs(int index,int nowK,int sumP,int sum)
{
	if(nowK==K&&sumP==N){
		if(sum>maxSum){
			maxSum = sum;
			ans = tmp;
		}
		return;
	}
    if(nowK>K||index<=0||sumP>N) return;
    dfs(index-1,nowK,sumP,sum);//不选
	tmp.push_back(index);
	dfs(index,nowK+1,sumP+v[index],sum+index);
	tmp.pop_back(); 
 //   dfs(index-1,nowK,sumP,sum);//不选
}
int main()
{
	scanf("%d%d%d",&N,&K,&P);
	int sqr = (int)sqrt(1.0*N);
	for(int i=0; i<=sqr; i++){
		v.push_back(pow(i,P));
	}
	dfs(v.size()-1,0,0,0);
	if(ans.size()==0){
		printf("Impossible\n");
		return 0;
	}
	printf("%d = ",N);
	for(int i=0; i<ans.size(); i++){
		printf("%d^%d",ans[i],P);
		if(i!=ans.size()-1){
			printf(" + ");
		}
		else printf("\n");
	}
	return 0;
}




能通过测试点2的代码:

#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
int N,K,P;
vector<int> v,tmp,ans;
int maxSum = -1;
void dfs(int index,int nowK,int sumP,int sum)
{
	if(nowK==K&&sumP==N){
		if(sum>maxSum){
			maxSum = sum;
			ans = tmp;
		}
		return;
	}
    if(nowK>K||index<=0||sumP>N) return;
 //   dfs(index-1,nowK,sumP,sum);//不选
	tmp.push_back(index);
	dfs(index,nowK+1,sumP+v[index],sum+index);
	tmp.pop_back(); 
   dfs(index-1,nowK,sumP,sum);//不选
}
int main()
{
	scanf("%d%d%d",&N,&K,&P);
	int sqr = (int)sqrt(1.0*N);
	for(int i=0; i<=sqr; i++){
		v.push_back(pow(i,P));
	}
	dfs(v.size()-1,0,0,0);
	if(ans.size()==0){
		printf("Impossible\n");
		return 0;
	}
	printf("%d = ",N);
	for(int i=0; i<ans.size(); i++){
		printf("%d^%d",ans[i],P);
		if(i!=ans.size()-1){
			printf(" + ");
		}
		else printf("\n");
	}
	return 0;
}




 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值