PAT1103

是一道搜索题目,没怎么用剪枝,题目给的时间比较充裕。

在写的过程中出现一个严重的逻辑错误,搜索的范围的出错了。按照我的算法应该是每一次都是从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();
}
View Code

 




 

 

posted @ 2017-07-15 20:06  MalcolmMeng  阅读(337)  评论(0编辑  收藏  举报