找鞍点(任意鞍点个数)
这几天初学C语言,在题库中找到一个经典的“找鞍点”的编程问题。一开始感觉挺简单的,实际写起来感觉逻辑很乱。在网上查阅了不少资料,有些是正确的,但是觉得不具被通用性,只能在题干条件限制上才能成功。
而且以小白我的能力,感觉要好一会才能理解(> _ <)
于是我自己写了一个,任何阶数,任何鞍点个数都可以的,通用的“找鞍点”程序(^ — ^)而且相当好理解(小声:至少我这么觉得,哈哈)
首先来看看题目
题干: 一个矩阵元素的“鞍点”是指该位置上的元素值在该行上最大、在该列上最小。本题要求编写程序,求一个给定的n阶方阵的鞍点。
输入格式:
输入第一行给出一个正整数n(1≤n≤6)。随后n行,每行给出n个整数,其间以空格分隔。
输出格式:
输出在一行中按照 “行下标 列下标”(下标从0开始)的格式输出鞍点的位置。
如果鞍点不存在,则输出“NONE”。题目保证给出的矩阵至多存在一个鞍点。
输入样例1:
4
1 7 4 1
4 8 3 6
1 6 1 2
0 7 8 9
输出样例1:
2 1
输入样例2:
2
1 7
4 1
输出样例2:
NONE
网上有不少是正确答案,我找了一个看的清楚一些的答案
这个代码你运行一下就知道,它是利用了“至多存在一个鞍点。”的条件的。我不是说按题要求不好,而是感觉太局限了。而且另外有一些代码在题库里跑居然超时了😂
如果改动一下以实现有多个鞍点的情况,改的地方太多了,而且越改越乱
这里有一个别人改的,你试试输入的矩阵的每个元素的值都是一样的(< _ <)嘻嘻。。完全不行。
所以我完全重写了一个独一无二的程序(^ — ^)
(反正我没在网上找到跟我一样的,如有雷同纯属巧合)
如果是我来找“鞍点”有这几步:
- 找到每一行的最大值(包括相等的)的元素,并用 “圆” 圈起来
- 找到每一列的最小值(包括相等的)的元素,并用 “方” 圈起来
- 找到即被 “圆” 又被 “方” 圈起来的,就是一个"鞍点"
具体实现是这样的:
//ISO c99
#include<stdio.h>
int main(void)
{
int n;
int count = 0;//统计鞍点个数
scanf("%d", &n);//输入矩阵阶数
int matrix[n][n];//储存矩阵
int saddle[n][n];
//记录鞍点位置,3表示是鞍点,2表示列最小,1表示行最大
//之所以用三个值表示不同的值是为了预留接口
//便于以后改进一下还可以单独求列最小,行最大
//按行输入
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
scanf("%d", &matrix[i][j]);
//初始化
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
{
saddle[i][j] = 0;//初始化行最大,0为假,1为真
}
//开始查找
for(int i = 0; i < n; i++)//查找行最大值
{
int max = matrix[i][0];
for(int j = 0; j < n; j++)
{
if(max < matrix[i][j])
max = matrix[i][j];
}
for(int j = 0; j < n; j++)//定位当前行的所有最大值
{
if(matrix[i][j] == max)
saddle[i][j] += 1;
}
}
for(int i = 0; i < n; i++)//查找列最小值
{
int min = matrix[0][i];
for(int j = 0; j < n; j++)
{
if(min > matrix[j][i])
min = matrix[j][i];
}
for(int j = 0; j < n; j++)//定位当前列的所有最小值
{
if(matrix[j][i] == min)
saddle[j][i] += 2;
}
}
//判断并输出
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
if(saddle[i][j] == 3)
{
count++;
printf("%d %d\n", i, j);
}
}
}
if(count == 0)
printf("NONE");
return 0;
}
这就是目前为止我的想法啦(^ _ ^)
感谢阅读!