目录
五、枚举算法的应用 acwing3708 求矩阵的鞍点 四川大学考研机试题
一、枚举的基本思想
将问题的所有可能的答案一一列举,然后根据条件判断此答案是否合适,保留合适的,丢弃不合适的。
二、枚举机构
循环+判断语句
三、枚举算法的一般步骤
-
理解问题和解空间:首先,要对问题进行彻底的分析和理解,确定解空间的范围和限制条件。
-
设定变量范围:根据问题的特定要求,设定问题的变量的取值范围。这些变量可以是数字、布尔值或其他类型的变量。
-
枚举组合方式:使用循环或递归等方法,遍历所有可能的组合方式。根据问题的要求,可以选择不同的枚举结构,如排列、组合、子集等。
-
判断条件和筛选解:在枚举过程中,根据问题的约束条件,筛选出满足特定条件的解。
-
分析时间复杂度:对于大规模的问题,枚举算法可能会变得非常耗时。因此,需要分析算法的时间复杂度,以确定是否需要进行优化。
-
代码框架如下:
-
1开始 2 3设定变量范围 4 5初始化结果或标记 6 7对每个变量进行枚举 8 对每种组合方式进行循环 9 判断是否满足条件 10 若满足条件 11 更新结果或执行相关操作 12 结束当前循环 13 14输出结果或执行最终操作 15 16结束
四、模版示例
# 问题:找到一组数中的最大(python代码)
# 问题:找到一组数中的最大值
nums = [1, 5, 3, 8, 2]
max_value = nums[0]
for num in nums:
if num > max_value:
max_value = num
print("最大值为:", max_value)
五、枚举算法的应用 acwing3708 求矩阵的鞍点 四川大学考研机试题
给定一个 n×m的整数矩阵,行的编号为 1∼n,列的编号为 1∼m,求矩阵中的所有鞍点。
鞍点,即该位置上的元素在该行上最大,在该列上最小。有可能有多个鞍点,也可能没有鞍点。
输入格式
第一行包含两个整数 n,m。
接下来 n行,每行包含 m个整数。
输出格式
输出所有鞍点的坐标和值。
输出优先级,整体从上到下,同行从左到右。
如果不存在鞍点,则输出 NO
。
数据范围
1≤n,m<10
矩阵元素取值范围 [1,9]。
输入样例:
3 4
1 2 3 4
1 2 3 4
1 2 3 4
输出样例:
1 4 4
2 4 4
3 4 4
代码
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 15;
int a[N][N];
int main()
{
int n,m;
cin>>n>>m;
//读入二维数组
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
//计数 大于0存在鞍点 等于0不存在鞍点
int cnt = 0;
//枚举这个数 是不是这行最大值,这列最小值
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
bool fr =true,fc =true;//枚举a[i][j]是所在行最大值所在列是不是最小值,fr、fc都是true
//先判断行 行变一次 列号变多次
for(int k=1;k<=m;k++)
if(a[i][k]>a[i][j])//大于a[i][j],则枚举a[i][j]失败,不是该行最大值,fr=talse
fr = false;
//接着判断列 列变一次 行号变多次
for(int k=1;k<=n;k++)
if(a[k][j]<a[i][j])//小于a[i][j],则枚举a[i][j]失败,不是该列最小值,fc=talse
fc = false;
if(fr&&fc)//枚举成功,数是行的最大值 列的最小值 计数的cnt++ 输出 ,endl代表换行
{
cnt++;
cout<<i<<" "<<j<<" "<<a[i][j]<<endl;
}
}
if(cnt==0)
cout<<"NO";
return 0;
}
值得注意,for循环嵌套
题中for循环一共用了四次,最外层循环i在变,向里一层j在变,最里面的并列的两个k在变,注意 理解这四个变量,弄清a[i][j]、a[i][k]、a[k][j]的含义。