【版本一:DFS递归版本,有一个测试点超时,27分】
虽然第一次尝试没有满分,但是超级无敌开心了!!第一次做PAT的压轴题,还好还好…
#include <bits/stdc++.h>
using namespace std;
int tmp[512];
int MAX=-1;
int ans[512];
bool flag=false;
void DFS(int index,int n,int k,int p)
{
int sum=0;
for(int i=0;i<k;i++)
sum+=pow(tmp[i],p);
if(index==k) //boundary
{
if(sum==n) //one possible answer
{
flag=true;
int summ=0;
for(int i=0;i<k;i++)
summ+=tmp[i];
if(summ>MAX) //one possible answer
{
MAX=summ; //update the value of MAXsum
for(int i=0;i<k;i++) //update the answer
ans[i]=tmp[i];
}
else if(summ==MAX) //further judge
{
bool fflag=false; //initially, no update is assumed
for(int i=0;i<k;i++)
if(ans[i]>tmp[i])
fflag=true;
if(fflag) //otherwise, update
{
for(int i=0;i<k;i++)
ans[i]=tmp[i];
}
}
else return; //the answer is disregarded
}
return; //this isn't the answer
}
sum-=pow(tmp[index],p);
while(true)
{
if((index==0) || (tmp[index]!=tmp[index-1]+1))
{
sum+=pow(tmp[index],p);
if(sum<=n)
{
for(int i=index+1;i<k;i++)
tmp[i]=1;
DFS(index+1,n,k,p);
}
else
{
tmp[index]--;
break;
}
sum-=pow(tmp[index],p);
tmp[index]++;
}
else break;
}
}
int main(void)
{
int n,k,p;
scanf("%d%d%d",&n,&k,&p);
for(int i=0;i<k;i++)
tmp[i]=1;
DFS(0,n,k,p);
if(flag)
{
printf("%d = ",n);
for(int i=0;i<k;i++)
{
if(i!=k-1)
printf("%d^%d + ",ans[i],p);
else
printf("%d^%d",ans[i],p);
}
}
else
{
printf("Impossible");
}
}
【版本二:增加剪枝条件(如果当前序列和小于可能解的序列和,则剪掉),并且为pow函数打表避免重复计算,25分】
雷!超时测试点2的时间压缩至7ms,但是测试点2竟然错误了,百思不得其解!!
#include <bits/stdc++.h>
using namespace std;
int tmp[512];
int MAX=-1;
int ans[512];
int power[21];
bool flag=false;
void DFS(int index,int n,int k)
{
int sum=0,summ=0;
for(int i=0;i<k;i++)
{
summ+=tmp[i];sum+=power[tmp[i]];
}
if(index==k) //boundary
{
if(sum==n) //one possible answer
{
flag=true;
if(summ>MAX) //one possible answer
{
MAX=summ; //update the value of MAXsum
for(int i=0;i<k;i++) //update the answer
ans[i]=tmp[i];
}
else if(summ==MAX) //further judge
{
bool fflag=false; //initially, no update is assumed
for(int i=0;i<k;i++)
if(ans[i]>tmp[i])
fflag=true;
if(fflag) //otherwise, update
{
for(int i=0;i<k;i++)
ans[i]=tmp[i];
}
}
else return; //the answer is disregarded
}
return; //this isn't the answer
}
sum-=power[tmp[index]];
summ-=tmp[index];
while(true)
{
if((index==0) || (tmp[index]!=tmp[index-1]+1))
{
sum+=power[tmp[index]];
summ+=tmp[index];
if(sum<=n && summ>=MAX)
{
for(int i=index+1;i<k;i++)
tmp[i]=1;
DFS(index+1,n,k);
}
else
{
tmp[index]--;
break;
}
sum-=power[tmp[index]];
summ-=tmp[index];
tmp[index]++;
}
else break;
}
}
int main(void)
{
int n,k,p;
scanf("%d%d%d",&n,&k,&p);
for(int i=0;i<k;i++)
tmp[i]=1;
for(int i=0;i<=20;i++)
{
power[i]=pow(i,p);
}
DFS(0,n,k);
if(flag)
{
printf("%d = ",n);
for(int i=0;i<k;i++)
{
if(i!=k-1)
printf("%d^%d + ",ans[i],p);
else
printf("%d^%d",ans[i],p);
}
}
else
{
printf("Impossible");
}
}
【版本三:把版本二的剪枝条件删掉,并且引入一个pow函数的表避免计算,并且DFS函数参数增加了sum一项,避免了每次DFS的一个O(k)级别的运算,30分】Accepted!第五个测试点通过时间为600ms,还可以接受。
#include <bits/stdc++.h>
using namespace std;
int tmp[512];
int MAX=-1;
int ans[512];
int power[20];
bool flag=false;
void DFS(int index,int n,int k,int sum)
{
if(index==k) //boundary
{
if(sum==n) //one possible answer
{
flag=true;
int summ=0;
for(int i=0;i<k;i++)
summ+=tmp[i];
if(summ>MAX) //one possible answer
{
MAX=summ; //update the value of MAXsum
for(int i=0;i<k;i++) //update the answer
ans[i]=tmp[i];
}
else if(summ==MAX) //further judge
{
bool fflag=false; //initially, no update is assumed
for(int i=0;i<k;i++)
if(ans[i]>tmp[i])
fflag=true;
if(fflag) //otherwise, update
{
for(int i=0;i<k;i++)
ans[i]=tmp[i];
}
}
else return; //the answer is disregarded
}
return; //this isn't the answer
}
while(true)
{
if((index==0) || (tmp[index]!=tmp[index-1]+1))
{
if(sum<=n)
{
for(int i=index+1;i<k;i++)
tmp[i]=1;
DFS(index+1,n,k,sum);
}
else break;
sum-=power[tmp[index]];
tmp[index]++;
sum+=power[tmp[index]];
}
else break;
}
}
int main(void)
{
int n,k,p;
scanf("%d%d%d",&n,&k,&p);
for(int i=0;i<k;i++)
tmp[i]=1;
int s=0;
while(true)
{
power[s]=pow(s,p);
if(power[s]>400) break;
s++;
}
DFS(0,n,k,k);
if(flag)
{
printf("%d = ",n);
for(int i=0;i<k;i++)
{
if(i!=k-1)
printf("%d^%d + ",ans[i],p);
else
printf("%d^%d",ans[i],p);
}
}
else
{
printf("Impossible");
}
}