矩阵鞍点(可能有多个)
Description
若矩阵Am´n中的某一元素A[i][j]是第i行中的最小值,同时又是第j列中的最大值,则称此元素为该矩阵的一个鞍点。假设以二维数组存放矩阵,试编写一个函数,确定鞍点在数组中的位置(若鞍点存在时),并分析该函数的时间复杂度。该程序可以测试多个案例。
Input
第一行输入测试案例数T 以后T块输入每个测试案例,每个测试案例之间空一行 每个测试案例第一行输入m与n(m与n均小于100) 然后是m行数据 每行共n个数据(这些数据全为整数)
Output
对每个案例输出所有的鞍点,鞍点的顺序从上到下,从左到右,每个鞍点输出格式为:"A[i][j]"其中i,j是实际鞍点对应数字 每个鞍点之间空一个空格,最后一个鞍点后无空格,如果没有鞍点,则输出“NO.”(注意NO后面有一个点’.’) 2个案例之间空一个空行
Sample Input
3
2 2
2 3
1 1
2 3
4 5 1
7 6 -1
2 3
1 2 3
2 1 3
Sample Output
A[1][1]
A[1][3]
NO.
思路:
第一步:创建a[m][n]和b[m][n],b[m][n]与a[m][n]对应。
第二步:输入矩阵A,并将数组b的元素全部初始化为0;
第三步:判断矩阵A中的每个元素是不是所在行中最小的数(由于可能有多个数相同且为最小,所以应该先确定最小的数的值,然后再判断该行中各元素值是否等于该值),是则让其对应的数组b中的元素值加1。
第四步:和第三步一样的操作,判断矩阵A中的元素是否为所在列中最大的数,是则让其对应的数组b中的元素值加1。
第五步:这时,数组b中的元素全部由0、1、2三个数字构成,如果某元素值为2,则说明其对应的数组a中的元素既是所在行中最小的元素,也是所在列中最大的元素,即鞍点。
第六步:输出。
注:这里设置了两个标志变量flag和sign,flag的用途是判断输出的鞍点是否为第一个鞍点,以此来满足输出的多个鞍点间都有空格,而最后一个鞍点后面没有空格的要求;sign的用途是判断是否有鞍点。
#include<stdio.h>
int main()
{
int T,m,n,i,j,k,max,min,flag,sign;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&m,&n);
int a[m][n],b[m][n];
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&a[i][j]);
b[i][j]=0; //初始化为0
}
}
flag=0;
for(i=0;i<m;i++) //找到行中最小元素
{
min=a[i][0];
for(j=1;j<n;j++)
{
if(a[i][j]<min) min=a[i][j];
}
for(j=0;j<n;j++)
{
if(a[i][j]==min) b[i][j]++;
}
}
for(j=0;j<n;j++) //找到列中最小元素
{
max=a[0][j];
for(i=1;i<m;i++)
{
if(a[i][j]>max) max=a[i][j];
}
for(i=0;i<m;i++)
{
if(a[i][j]==max) b[i][j]++;
}
}
sign=1;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
if(b[i][j]==2)
{
flag=1;
if(sign)
{
printf("A[%d][%d]",i+1,j+1);
sign=0;
}
else printf(" A[%d][%d]",i+1,j+1);
}
}
}
if(flag==0) printf("NO.\n");
else printf("\n");
printf("\n");
}
return 0;
}