PTA习题:求矩阵鞍点的个数

  • 题目描述
  • 解题思路
  • 参考答案
  • 测试用例
  • 小结


题目描述

一个矩阵元素的“鞍点”是指该位置上的元素值在该行上最大、在该列上最小。

本题要求编写程序,求一个给定的n阶方阵的鞍点。

输入格式: 输入第一行给出一个正整数n(1≤n≤6)。随后n行,每行给出n个整数,其间以空格分隔。

输出格式: 鞍点的个数

输入样例1:

4
1 7 4 1
4 8 3 6
1 6 1 2
0 7 8 9

输出样例1:

1

输入样例2:

2
1 7
4 1

输出样例2:

0

输入样例3:

3
6 6 6
6 6 6
6 6 6

输出样例3:

9

作者和要求
作者: 陈春晖
单位: 浙江大学
时间限制: 400 ms
内存限制: 64 MB
代码长度限制: 16 KB

解题思路

  1. 求出矩阵各行最大值,存入row_max_list列表中。
  2. 求出矩阵各列最小值,存储column_min_list列表中。
  3. 逐行,逐列地扫描矩阵,看元素values[ row ][ column ]是否是鞍点。如果是,则鞍点个数加1。
  4. 判别元素values[ row ][ column ]是否是鞍点的做法:如果values[row][column] == row_max_list[row] 且 values[row][column] == column_min_list[column]成立,则是鞍点,否则不是。
  5. 第3步可以优化,减少参与比对的矩阵元素的个数。不过,由于矩阵的行数n不大,所以没多大必要。

参考答案

n = int(input())
values = [[int(s) for s in input().split()] for i in range(n)]
row_max_list = [max(values[i]) for i in range(n)]  #各行最大值
column_min_list = []  #用来存储各列最小值
#求各列最小值
for column in range(n):
    column_min = values[0][column]
    for row in range(1, n):
        if values[row][column] < column_min:
            column_min = values[row][column]
    column_min_list.append(column_min)  #column列最小值

count = 0
#逐行、逐列地扫描矩阵
for row in range(n):
    for column in range(n):
        if values[row][column] == row_max_list[row] and values[row][column] == column_min_list[column]:
            count += 1  #鞍点个数加1

print(count)

测试用例

  1. 题目描述给出的第一组测试用例覆盖的是一般情形。有1个鞍点。
  2. 题目描述给出的第二组测试用例覆盖的是没有鞍点的情形。
  3. 题目描述给出的第三组测试用例覆盖的是每个元素都是鞍点的情形。
  4. n=1的边界情形。
    样例输入
    1
    3
    样例输出
    1
  5. n=6的边界情形。
    样例输入
    6
    6 5 4 3 2 1
    5 4 3 2 1 0
    4 3 2 1 0 -1
    3 2 1 0 -1 -2
    2 1 0 -1 -2 -3
    1 0 -1 -2 -3 -4
    样例输出
    1

小结

  1. 先求出各行最大值,各列最小值的好处:在逐行、逐列地扫描矩阵判别各个元素是否是鞍点时,无需再求所在行最大值,所在列最小值。
  2. 如果你对矩阵的使用不够熟练,你会绝对这道题目有难度。事实上,算法层面上难度不大。