是一道搜索题目,没怎么用剪枝,题目给的时间比较充裕。
在写的过程中出现一个严重的逻辑错误,搜索的范围的出错了。按照我的算法应该是每一次都是从factor递减到1,刚开始写的时候被所谓的“选择和不选择“误导,
最后还是通过单步调试发现的= =
还有值得注意的一点是factor是从sqrt(N)开始的
讲道理按照“选择和不选择“的思路也是可以的,不过要做一点预处理,留个坑来填。
#include<cstdio>
#include<vector>
#include<cmath>
using namespace std;
int N,K,P;
int Pow(int factor)
{
int ans=1;
for(int i=0;i<P;i++)
{
ans*=factor;
}
return ans;
}
bool succ=false;
vector<int>ans;
vector<int>seq;
bool cmp()
{
int ansSum=0,seqSum=0;
for(int i=0;i<ans.size();i++)
{
ansSum+=ans[i];
}
for(int j=0;j<seq.size();j++)
{
seqSum+=seq[j];
}
int ansp=0,seqp=0;
while(ansp<ans.size()&&seqp<seq.size()&&ans[ansp]==seq[seqp]){
ansp++;
seqp++;
}
if(ansSum==seqSum)
return ans[ansp]<seq[seqp];
return ansSum<seqSum;
}
void debug()
{
for(int i=0;i<seq.size();i++)
{
printf("%d ",seq[i]);
}
printf("\n\n");
}
void dfs(int factor,int sum)
{
if(seq.size()==K){
if(sum==N){//成功
succ=true;
if(cmp()){
ans=seq;
}
//ans=seq;
}
return ;
}
if(sum>=N){
return ;
}
for(int i=factor;i>=1;i--)
{
seq.push_back(i);
dfs(i,sum+Pow(i));
seq.pop_back();
}
}
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d%d",&N,&K,&P);
dfs((int)sqrt(N),0);
if(!succ)printf("Impossible\n");
else {
printf("%d =",N);
//169 = 6^2 + 6^2 + 6^2 + 6^2 + 5^2
//169 = 6^2 + 6^2 + 6^2 + 6^2 + 5^2
for(int i=0;i<ans.size();i++)
{
printf(" %d^%d",ans[i],P);
if(i<ans.size()-1)printf(" +");
else printf("\n");
}
}
//getchar();
}