考虑方程式:a^3 + b^3 = c^3 + d^3
其中:“^”表示乘方。a、b、c、d是互不相同的小于30的正整数。
这个方程有很多解。比如:
a = 1,b=12,c=9,d=10 就是一个解。因为:1的立方加12的立方等于1729,而9的立方加10的立方也等于1729。
当然,a=12,b=1,c=9,d=10 显然也是解。
如果不计abcd交换次序的情况,这算同一个解。
你的任务是:找到所有小于30的不同的正整数解。把a b c d按从小到大排列,用逗号分隔,每个解占用1行。比如,刚才的解输出为:
1,9,10,12
不同解间的顺序可以不考虑。
对于这种题目,首先我们要做的是预处理,因为一共只有30个数字,所以可以事先将1-30中的每个数字求出其立方然后保存起来,便于后面运算。然后,我们对这30个数字取四个进行全排列,总共就是P(30,4)种可能,其实还是很少的,所以枚举应该不会出现大问题,所以问题的关键是怎样求全排列,首先,我们定义两个数组,cubic[]和used[],分别代表那三十个数的立方和每个数字是否被使用,然后,我们通过一个递归程序,递归总共四层,用count来控制,每一层代表一个加数,temp[]用来临时存储这四个数,每使用一个数,就将这个数标记一下,别忘了在回溯的时候解除标记,这样就可以无重复全排列了,取出四个数之后,判断一下等式是否成立,如果成立并且之前没有出现过的话,就将这组解存到result[][]中,最后输出result[][]。
#include<iostream>
#include<stdio.h>
#include<memory.h>
#include<algorithm>
using namespace std;
int cubic[31];
bool used[31];
int result[100][4];
int temp[5];
int p,q;
void init()
{
int i;
p=0;
q=0;
for(i=1;i<=30;i++)
{
cubic[i]=i*i*i;
}
memset(used,false,sizeof(used));
}
bool search()
{
int i;
sort(temp,temp+5);
for(i=0;i<p;i++)
{
if((result[i][0]*result[i][0]*result[i][0])==temp[1]&&(result[i][1]*result[i][1]*result[i][1])==temp[2])
return true;
}
return false;
}
void judge()
{
if(temp[1]+temp[2]==temp[3]+temp[4])
{
if(search())
return;
for(int i=1;i<=30;i++)
{
for(int j=1;j<=4;j++)
{
if(temp[j]==cubic[i])
{
result[p][q++]=i;
}
}
}
p++;
q=0;
}
}
void cal(int count)
{
if(count==5)
{
judge();
return;
}
int i;
for(i=1;i<=30;i++)
{
if(used[i]==false)
{
temp[count]=cubic[i];
used[i]=true;
cal(count+1);
used[i]=false;
}
}
}
int main()
{
int i,j;
init();
cal(1);
for(i=0;i<p;i++)
{
for(j=0;j<4;j++)
cout<<result[i][j]<<' ';
cout<<endl;
}
return 0;
}