在二维数组中寻找最小鞍点1181(该行最大值,该列最小值)(2种思路)

题目描述

找出一个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);
	  //总结,我个人并不建议使用这一种方法,虽然在计算某些较小数据时数据输出的结果是一样的,也容易理解
	  //但是在计算大量数据时超时了,而且在对应寻找最小鞍点的方面我还没有进行优化,
	  //我个人建议学习第一种思路,这种思路仅作参考 
      
  }

创作不易感谢您的支持。

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值