什么是鞍点?
在矩阵中,一个数在所在行中为最大值,而在其所在列中为最小值,则该点称为鞍点。
如图1所示,3就是一个鞍点,当然一行中也可能出现多个鞍点,如图2所示。
解题思路:
先找出每一行中的最大值,然后再判断最大值在所处的列中是不是最小值,如果是,则证明该点为鞍点,否则,则该点不是鞍点。
代码实现:1、输入矩阵的行和列,之后给该矩阵赋值。
int row = 0; // 数组的行 int col = 0; // 数组的列 int max_row = 0; // 每一行的最大值 printf("请输入数组的行数:"); scanf("%d", &row); printf("n请输入数组的列数:"); scanf("%d", &col); int arr[row][col]; // 数组初始化,开辟空间 printf("n给该数组赋值...n"); for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { printf("请输入第%d行第%d列的值:", i, j); scanf("%d", &arr[i][j]); printf("n"); } }2、找出每一行中的最大值,如果出现多个相同的最大值,则用flag变量来存储,初始为0(有2个相同flag为1,3个相同flag为2,以此类推)
// 找出最大值,如果出现多值相同的情况,flag++ for (int i = 0; i < row; i++) { int flag = 0; // 判断每行是否出现多值相同的情况 int col_index = 0; // 初始列下标记为0 max_row = arr[i][0]; // 下次循环开始前,每行最大值重置 for (int j = 1; j < col; j++) { if (max_row < arr[i][j]) { max_row = arr[i][j]; col_index = j; //记录当前行最大值下标 } else if (max_row == arr[i][j]) { flag++; // 记录有几个相同的最大值 col_index = j; //记录当前行最大值下标 } } }3、找出每一行最大值之后,再对其所在列进行判断,有两种情况,第一种是每一行只有一个最大值,第二种是每一行存在多个最大值。
// 求得每一行最大值之后,对每一列进行判断,看是否为最小值(鞍点) // 先判断是否出现多值相同情况 if (flag) { do { int mflag = 1; // 判断是否为列最小值的标志 int min_col = arr[i][col_index - flag]; // 默认当前行最大值为列最小值 for (int k = 0; k < row; k++) { if (min_col > arr[k][col_index - flag]) // 列不变,行变化 { mflag = 0; // 如果该值比所在列其他值大,mflag = 0,直接退出循环 break; } } if (mflag) // 所在列遍历结束后,如果mflag为1,则证明该点是最小值,即该点是鞍点 { printf("第%d行第%d列是鞍点n", i, col_index - flag); } } while (flag--); } else { // 如果每一行中的值都不一样,没有出现多值相同的情况 int mflag = 1; // 判断是否为列最小值的标志 int min_col = arr[i][col_index - flag]; // 默认当前行最大值为列最小值 for (int k = 0; k < row; k++) { if (min_col > arr[k][col_index - flag]) // 列不变,行变化 { mflag = 0; break; } } if (mflag) { printf("第%d行第%d列是鞍点n", i + 1, col_index - flag + 1); } } 完整代码 #include <stdio.h>int main(){ int row = 0; // 数组的行 int col = 0; // 数组的列 int max_row = 0; // 每一行的最大值 printf("请输入数组的行数:"); scanf("%d", &row); printf("n请输入数组的列数:"); scanf("%d", &col); int arr[row][col]; // 数组初始化,开辟空间 printf("n给该数组赋值...n"); for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { printf("请输入第%d行第%d列的值:", i, j); scanf("%d", &arr[i][j]); printf("n"); } } // 找出最大值,如果出现多值相同的情况,flag++ for (int i = 0; i < row; i++) { int flag = 0; // 判断每行是否出现多值相同的情况 int col_index = 0; // 初始列下标记为0 max_row = arr[i][0]; // 下次循环开始前,每行最大值清零(有bug) for (int j = 1; j < col; j++) { if (max_row < arr[i][j]) { max_row = arr[i][j]; col_index = j; //记录当前行最大值下标 } else if (max_row == arr[i][j]) { flag++; col_index = j; //记录当前行最大值下标 } } //printf("第%d行中的最大值是%d,列的下标为%dn", i, max_row, col_index); // 求得每一行最大值之后,对每一列进行判断,看是否为最小值(鞍点) // 先判断是否出现多值相同情况 if (flag) { do { int mflag = 1; // 判断是否为列最小值的标志 int min_col = arr[i][col_index - flag]; // 默认当前行最大值为列最小值 for (int k = 0; k < row; k++) { if (min_col > arr[k][col_index - flag]) // 列不变,行变化 { mflag = 0; break; } } if (mflag) { printf("第%d行第%d列是鞍点n", i, col_index - flag); } } while (flag--); } else { // 如果每一行中的值都不一样 int mflag = 1; // 判断是否为列最小值的标志 int min_col = arr[i][col_index - flag]; // 默认当前行最大值为列最小值 for (int k = 0; k < row; k++) { if (min_col > arr[k][col_index - flag]) // 列不变,行变化 { mflag = 0; break; } } if (mflag) { printf("第%d行第%d列是鞍点n", i, col_index - flag); } } } return 0;} 测试结果当输入3行3列时,第0行第2列是鞍点
123456789
当输入3行4列时,第一行全为鞍点
111123456789