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;
}