找鞍点(任意鞍点个数)

找鞍点(任意鞍点个数)

这几天初学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

网上有不少是正确答案,我找了一个看的清楚一些的答案

这个代码你运行一下就知道,它是利用了“至多存在一个鞍点。”的条件的。我不是说按题要求不好,而是感觉太局限了。而且另外有一些代码在题库里跑居然超时了😂
如果改动一下以实现有多个鞍点的情况,改的地方太多了,而且越改越乱
这里有一个别人改的,你试试输入的矩阵的每个元素的值都是一样的(< _ <)嘻嘻。。完全不行。

所以我完全重写了一个独一无二的程序(^ — ^)
(反正我没在网上找到跟我一样的,如有雷同纯属巧合

如果是我来找“鞍点”有这几步:

  1. 找到每一行的最大值(包括相等的)的元素,并用 “圆” 圈起来
  2. 找到每一列的最小值(包括相等的)的元素,并用 “方” 圈起来
  3. 找到即被 “圆” 又被 “方” 圈起来的,就是一个"鞍点"

具体实现是这样的:

//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;
}

这就是目前为止我的想法啦(^ _ ^)

感谢阅读!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值