题目描述
找出一个2维数组矩阵的鞍点,即该位置上的元素在该行中最大,在该列中最小,可能不存在鞍点,如果存在多个,输出最小的那个!
输入要求
输入 n,m表示二维矩阵的行数和列数,然后根据行列数输入n*m个数据构成一个二维矩阵。
输出要求
如果存在鞍点,则输出该鞍点的值,如果不存在则输出not exist。
输入样例
4 5 1 2 3 4 5 2 4 6 8 10 3 6 9 12 15 4 8 12 16 20
输出样例
5
- 思路1:记录下每行的最大值所在的列数,每列最小值所在行数。最后遍历 每行找到的列数,那么第i行“最大值所在列”(这是个列数)的“最小值所在行”(这是个行数)刚好是i的话,我们就找到了鞍点。
- 思路2:先找到第x行中最大值所在列,这一行刚好是此列中最小的的话,这就是个鞍点。
- 思路1代码段:
#include<stdio.h>//记录下每行的最大值所在的列数,每列最小值所在行数。 //最后遍历 每行找到的列数,那么第i行“最大值所在列”(这是个列数)的“最小值所在行” //(这是个行数)刚好是i的话,我们就找到了鞍点。 int main()//此题目为模板题,建议背诵记忆 { int a[105][105],x[105]={0},y[105]={0},flag=0,n,m,i,j,Min; /* x代表第i行的最大值所在的列数,y代表最第i列最小值所在行数 */ scanf("%d%d",&n,&m);//输入n行,m列 for(i=0;i<n;i++) for(j=0;j<m;j++){//寻找出每一行的最大值,并把最大值对应下标存储到x[i]里 //寻找出每一列的最小值,并把最小值对应下标存储到y[j]里 scanf("%d",&a[i][j]); if(a[i][j] > a[i][ x[i] ]) x[i]=j;//这段代码建议慢慢思考,寻找最值下标并存储 if(a[i][j] < a[ y[j] ][j]) y[j]=i;//一开始i和j都是0 } for(i=0;i<n;i++){//遍历每行找到的列数, //那么第i行最大值所在列和最小值所在行如果同时为i,我们就找到了鞍点。 //因为根据鞍点的定义,是在该行上最大的数,在该列最小的数 //此处的flag用来标记判断是否找到鞍点,若找到则flag被赋值为1 // 4 5 //1 2 3 4 5 //2 4 6 8 10 //3 6 9 12 15 //4 8 12 16 20 //举个例子 看这道题,第0行最大数的列数==4,是末位那个5,列数为4 //从数列4开始自上而下顺序查找,该列最小数的行数==0 ,最上面那个5, 可以 称这个位置为(0,4) //仔细看 // 第0行最大数列==4,第4列最小数行数==0 //如果前面的那个0等于后面的那个0 //则这个数为鞍点 //即外面的for循环从0行开始遍历 //当第i行最大数列==j,第4列最小数行数==k; //当i==k时,该点为鞍点 //以上举例说明为 y[ x[i] ] == i 的解释 /* x代表第i行的最大值所在的列数,y代表最第i列最小值所在行数 */ if( y[ x[i] ] == i && (flag == 0 || Min>a[i][ x[i] ]) )//第一次未发现鞍点,成立的条件是flag==0, //发现鞍点后,成立条件是 Min>a[i][ x[i] ],因为题目要求是寻找最小鞍点,若发现的鞍点比原来鞍点大,就不存储 { Min=a[i][ x[i] ]; flag=1; } } if(flag==1)//用flag来判断是否存在鞍点并输出 printf("%d\n",Min); else printf("not exist\n"); }
思路2代码段:我个人建议学习第一种思路,第二种思路在计算大量数据时会超时
#include<stdio.h>//先找到第x行中最大值所在列,这一行刚好是此列中最小的的话,这就是个鞍点
int main()
{
int m,a[100][100],c,i,j,n,max,flat=0,k=0,p=0;
scanf("%d%d",&n,&m);//n行,m列,分别存储数据到这个二维数组里
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
scanf("%d",&a[i][j]);
}
}
for(i=0;i<n;i++)//函数每一行的列数的遍历的
//注意看这个大for循环里包含了1个小for循环
{ flat=0;
max=a[i][0];//先把每行第一个假设为最大值
//通过遍历每一行,找到最大值并记录下标传递给k
for(j=0;j<m;j++)
{
if(max<=a[i][j])
{
max=a[i][j];k=j;
}
}
for(i=0;i<n;i++)//将第i行中最大的数的那一列记为k列
//在这一列,从上往下依次寻找,判断是否该值为这整列中的最小值,若是,则为鞍点,
//若发现有比它更小的,则它不是鞍点
{
if(max>a[i][k])
{
flat=1;break;
}
}
if(flat==0)
{
printf("%d\n",max);p=1;
}
}
if(p==0)
printf("not exist\n",flat);
//总结,我个人并不建议使用这一种方法,虽然在计算某些较小数据时数据输出的结果是一样的,也容易理解
//但是在计算大量数据时超时了,而且在对应寻找最小鞍点的方面我还没有进行优化,
//我个人建议学习第一种思路,这种思路仅作参考
}
创作不易感谢您的支持。