PAT1103

1,题目

这里。。。

2,思路

  • dfs剪枝

3,这题遇到的坑。。。

  • 在预先求出P次方的时候,用函数pow,出了大问题!!!
     double pow (double base     , double exponent);
      float pow (float base      , float exponent);
long double pow (long double base, long double exponent);
     double pow (Type1 base      , Type2 exponent);        // additional overloads

这是参考手册的关于pow函数的描述。而在一开始的程序中,我是这样求解的:

	for(index=1;; ++index) {
        if(pow(index,P)>N)
            break;
        factorP[index]=pow(index,P);
    }

其中

int factorP[400],index=0;

可见pow的返回值是float、double,而我上述的写法会将double强制转换为int,这样导致数据失真。。。如下

可以看到计10的平方和5的平方都出错了,这就是double强制转int 导致失真!!!

  • 改为下列写法后:
	for(index=1;;++index){
        double temp=pow(index,P);
        if(temp>N) break;
        factorP[index]=temp;
    }

程序就正确了。

4,代码

#include<stdio.h>
#include<math.h>
#include<vector>
using namespace std;
int N,K,P;
int factorP[400],index=0;
vector<int>  path,tempPath;
int KPSum=0;
int sum_factor=-1;
void dfs(int pos) {
    if(pos>=index) return;
    tempPath.push_back(pos);
    KPSum+=factorP[pos];
    int len=tempPath.size();
    if(len==K){
        if(KPSum==N){
            int temp_sum_factor=0;
            for(int i=0;i<K;++i) temp_sum_factor+=tempPath[i];
            if(temp_sum_factor>sum_factor){
                sum_factor=temp_sum_factor;
                path=tempPath;
            }else if(temp_sum_factor==sum_factor){
                for(int i=K-1;i>=0;--i){
                    if(tempPath[i]>path[i]){
                        path=tempPath;
                    }else if(tempPath[i]<path[i]) break;
                }
            }
        }
        tempPath.pop_back();
        KPSum-=factorP[pos];
        return;
    }
    for(int i=pos;i<index;++i){
        if(KPSum+factorP[i]<=N)
            dfs(i);
    }
    tempPath.pop_back();
    KPSum-=factorP[pos];
}
int main() {
    scanf("%d %d %d",&N,&K,&P);
    for(index=1;;++index){
        double temp=pow(index,P);
        if(temp>N) break;
        factorP[index]=temp;
    }
    for(int i=1;i<index;++i){
        tempPath.clear();
        dfs(i);
    }
    if(sum_factor==-1)
        printf("Impossible\n");
    else {
        printf("%d = ",N);
        int len=path.size();
        for(int i=len-1; i>=0; --i) {
            if(i==len-1) {
                printf("%d^%d",path[i],P);
            } else {
                printf(" + %d^%d",path[i],P);
            }
        }
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值