介绍
枚举就是一一列举,对于问题发生的所有可能一一列举出来,并逐个进行验证。
例子:比如想给朋友打电话时,但是有一位号码记不住了,我们可以通过一个一个尝试的方法来解决这个问题。
步骤
(1)根据题干要求确定变量个数、变量取值范围、枚举顺序。
(2)根据条件来进行确定变量间大小关系。
(3)结合具体问题来减少重复次数。
注意
(1)建立简洁的数据模型。数据模型中的变量个数尽可能少,且变量之间相互独立,缩小搜索的维度。
(2)减小搜索的空间。利用题干已给条件和变量间的关系来进行缩小变量的取值范围,减少循环体被执行的次数。
(3)采用合适的搜索顺序。搜索空间的次序要与数学模型中的表达式一致。
纸上得来终觉浅,绝知此事要恭行!
实例:完美立方
条件限制
a 的值从小到大,每行输出一个完美立方等式,其中b c d按照非降序排列输出,如果两个完美立方中的a的值相等,则b小的值先输出,如果b值相等,c小的值先输出;在b,c都相等的情况下,d值小的先输出。
问题分析
(1)由题干可以知,需要四个变量 a b c d。
(2)考虑特殊情况,(b,c,d)在下列情况下没有对应的a值满足完美立方
(2,2,2)(2,2,3)(2,3,3)
(3,3,3)(2,2,4) (2,3,4)
所以a>=6(2^3+3^3+4^3>5^3)
2<=b<=c<=d<a,将b c d的上限定为(a-1)。
(3)在判断是否为完美立方,对于每个数的立方需要重复计算,为了避免这 种情况,可以使用一个数组(S)专门用来存储立方值,使用是直接访问即可。
操作代码
using namespace std;
int main() {
int N, a, b, c, d;
int total=0;
printf("请输入N的值:\n");
scanf_s("%d",&N);
int* cube = new int[N+1]; //动态分配存储空间
for (int i = 2; i <= N; i++) {
cube[i] = i * i * i; //预处理2-的立方
}
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;
}