算法思想第一站:枚举_枚举

介绍

 ​  枚举就是​一一列举​,对于问题发生的所有可能一一列举出来,并逐个进行验证。

例子​:​比如想给朋友打电话时,但是有一位号码记不住了,我们可以通过一个一个尝试的方法来解决这个问题。

步骤

(1)根据题干要求确定​变量个数、变量取值范围、枚举顺序​。

(2)根据条件来进行确定​变量间大小关系​。

(3)结合具体问题来​减少重复次数​。

注意

(1)​建立简洁的数据模型​。数据模型中的变量个数尽可能少,且变量之间相互独立,缩小搜索的维度。

(2)​减小搜索的空间。​利用题干已给条件和变量间的关系来进行缩小变量的取值范围,减少循环体被执行的次数。

(3)​采用合适的搜索顺序​。搜索空间的次序要与数学模型中的表达式一致。

纸上得来终觉浅,绝知此事要恭行!

实例:完美立方

算法思想第一站:枚举_枚举_02

条件限制

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​)专门用来存储立方值,使用是直接访问即可。

操作代码

#include<iostream>
#include<cstdio>
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;
}

结果演示

算法思想第一站:枚举_枚举_03