题目内容:
给定一个n*n矩阵A。矩阵A的鞍点是一个位置(i,j),在该位置上的元素是第i行上的最大数,第j列上的最小数。一个矩阵A也可能没有鞍点。
你的任务是找出A的鞍点。
输入格式:
输入的第1行是一个正整数n, (1<=n<=100),然后有n行,每一行有n个整数,同一行上两个整数之间有一个或多个空格。
输出格式:
对输入的矩阵,如果找到鞍点,就输出其下标。下标为两个数字,第一个数字是行号,第二个数字是列号,均从0开始计数。
如果找不到,就输出
NO
题目所给的数据保证了不会出现多个鞍点。
输入样例:
4
1 7 4 1
4 8 3 6
1 6 1 2
0 7 8 9
输出样例:
2 1
时间限制:500ms内存限制:32000kb
思路:
利用二维数组进行输入,先输入n确定二维数组大小,遍历输入;
再利用等大的初始化为0的二维数组记录最大最小值的位置(有最大/小值对应位置元素加1),利用一个双重循环按行找最大值,按列找最小值,需要注意的是一行中最大值的位置/一列中最小值的位置可能不止一个(输入数据未说明是不同的),故需进行遍历找出与每行/列最大/小值相同的值并在记录状态数组的对应位置上的元素进行加1;
输出时循环遍历二维数组,鞍点既满足一行的最大值又满足一列的最小值,对应状态应该为2,查找等于2的元素位置,输出,如果没有查询到则输出NO
#include<stdio.h>
int main()
{
int n;
scanf("%d", &n);
int a[n][n];
int i,j;
// 输入
for( i=0 ; i<n ; i++ ){
for( j=0 ; j<n ; j++ ){
scanf("%d", &a[i][j]);
}
}
// 判断每行中最大值所在的位置和每列中最小值所在的位置:
//利用初始化为全0的二维数组标记状态,每行中最大值所在位置的元素+1,每列中最小值所在位置的元素+1,这样如果数组中有值为2的元素,其所在位置就是鞍点
int check[n][n]; // 状态标记矩阵
for ( i=0 ; i<n ; i++ ){ // 数组初始化
for( j=0 ; j<n ; j++ ){
check[i][j] = 0;
}
}
for( i=0 ; i<n ; i++ ){
int maxid = 0, minid = 0; // 记录最大值位置
for( j=1 ; j<n ; j++ ){
if( a[i][maxid]<a[i][j] ){ // 每行中最大值所在位置
maxid = j;
}
if( a[minid][i]>a[j][i]){ // 每列中最小值所在位置
minid = j;
}
}
check[i][maxid] += 1;
check[minid][i] += 1;
for( j=0 ; j<n ; j++ ){ // 检查每行最大值和每列最小值是否有等大的值,对应状态标记数组位置元素+1
if( a[i][maxid]==a[i][j] && j!=maxid ){ // 每行中最大值所在位置
check[i][j] += 1;
}
if( a[minid][i]==a[j][i] && j!=minid ){ // 每列中最小值所在位置
check[j][i] += 1;
}
}
}
// 输出
int p = 0; // 是否存在数值为2的元素的标记 0表示不存在
for( i=0 ; i<n ; i++ ){
for( j=0 ; j<n ; j++ ){
if( check[i][j]==2 ){
printf("%d %d", i , j);
p ++;
break;
}
}
}
if( p==0 ) printf("NO");
return 0;
}