题目描述
这个问题相当简单,就是枚举。唯一考虑的是它们的大小顺序。
#include<stdio.h>
int main()
{
int N;
scanf("%d",&N);
int i,j,k,n;
for(i=2;i<=N;i++)
for(j=2;j<=N;j++)
for(k=2;k<=N;k++)
{
if(k<j) continue;
for(n=2;n<=N;n++)
{
if(n<k)
continue;
if(i*i*i==j*j*j+k*k*k+n*n*n)
printf("Cube = %d, Triple = (%d,%d,%d)\n",i,j,k,n);
}
}
return 0;
}
解题思路:此题可采用枚举的方式,对a,b,c,d的值按照一定的顺序进行枚举,在满足a^3=b^3+c^3+d^3时按照要求输出。题目要求按照a的值从小到大输出,并且b,c,d按照非降序排列,所以枚举的关键在于以下两点。
(1)确定a,b,c,d的取值范围枚举顺序。1.考虑到(b,c,d)取(2,2,2),(2,2,3),(2,3,3),(3,3,3),(2,2,4),(2,3,4)时都没有满足条件的a,所以a>=6(2^3+3^3+4^3>5^3),并且a应该在循环的最外层,由小到大枚举;2.由题意可知2<=b<=c<=d<a,所以循环由外至内为b,c,d,它们的取值上限都是a-1,下限分别是2,b,c.
(2)避免重复计算。在循环的最内层,需要在判断是否满足a^3=b^3+c^3+d^3时计算4次立方值,而a,b,c,d在循环中会经常取之前取过的值,因此会产生很多次重复计算,这里1<a.b.c.d<=N,因此实际上是最多只需要计算2~N的立方。可以考虑用一个数组存储事先计算好的立方值,使用时直接访问即可。
官方代码:
#include<cstdio>
int main()
{
int N,a,b,c,d;
int cube[101];
scanf("%d",&N);
for(int i = 2;i<=N;i++) //预处理2~N
cube[i]=i*i*i;
for(a=6;a<=N;a++) //枚举a
for(b=2;b<a;b++) //枚举b
for(c=b;c<a;c++) //枚举c
for(d=c;d<a;d++) //枚举d
if(cube[a] == cube[b] + cube[c] + cube[d])
//判断条件是否成立
printf("Cube = %d, Triple = (%d,%d,%d)\n",a,b,c,d);
return 0;
}
实现技巧:
(1)使用数组储存2~N的立方,避免重复计算。
(2)缩小枚举变量的取值范围,减少无用循环次数。
(3)输出时使用printf比cout在速度上具有一定优势。