[洛谷]B2102 计算鞍点

传送门:计算鞍点 - 洛谷

审题

        (概念)鞍点:矩阵中的一个元素,它是所在行的最大值,并且是所在列的最小值。

变量要求 : 5X5的矩阵

需要判断最大值和最小值,就需要储存他们的数组。

过程: 我们需要对数组的每一行,每一列进行比较,得出最大值和最小值

            利用最大值和最小值找出鞍点并输出。

思路过程

找出极值

对于找最大值和最小值的对比,通常是采用maxn和minn充当中间值一个一个比大小

也就是以下代码

//ma[6]是用于存储每行最大值下标的数组,相当于指针
int maxn;//比较器
for(int i=1;i<=5;i++){//行数
    maxn=a[i][1];//用每行第一个数据比较
    ma[i]=1;//要提前赋值,不然如果第一个数据是最大的就会显示0,也可以定义时赋
	for(int j=2;j<6;j++){//列数
		if(a[i][j]>maxn){//求最大值
			maxn=a[i][j];
			ma[i]=j;//记录
		}
    }
}
//mi[6]是用于记录每列最小值下标的数组,相当于指针
int minn;
for(int i=1;i<6;i++){//列数
		minn=a[1][i];//用每列第一个数据比较
        mi[i]=1;
		for(int j=2;j<6;j++){//行数
			if(a[j][i]<minn){
				minn=a[j][i];
				mi[i]=j;
			}
		}
	}

仔细观察便会发现,两个代码的框架大差不差的,只不过是行和列颠倒了而已,就可以把他们写在一起。

                      另外,maxn及minn在每次循环中都是变化的,于是就可以把他们定义在循环内

就是接下来的代码

for(int i=1;i<6;i++){
	int maxn=a[i][1],minn=a[1][i];
    ma[i]=mi[i]=1;
	for(int j=2;j<=5;j++){
		if(a[i][j]>maxn){
			maxn=a[i][j];
			ma[i]=j;
	    }
		if(a[j][i]<minn){
			minn=a[j][i];
			mi[i]=j;
		}
	}
}

检索鞍点

因为“鞍点”既要满足行最大值,又要满足列最小值。

所以我们在检索5个最大值或最小值时可以判断这个坐标上的值是否同时是他所在的那一行或列中的最大值或最小值。

没看懂? 看这你就懂了,因为ma[x(行数)]=y(列数),意为x行的最大值在y列

                                                mi[x(列数)]=y(行数),意为x列的最小值在x行

意思就是说    mi[ma[i]]=i    时 a[i][ma[i]] 既满足i行上的最大值,又满足 ma[i] 列上的最小值

如下图,题目给出的例子,做个假设

若i=4, ma[i]=1, mi[ma[i]]=4, 而 i 恰好又等于 mi[ma[i]] ,这时 a[i][ma[i]] 也就是 a[4][1] 就是鞍点

a[6][6]mi[1]=4mi[2]=3mi[3]=4mi[4]=1mi[5]=4
ma[1]=1113569
ma[2]=11247810
ma[3]=51026911
ma[4]=186472
ma[5]=51510112025

理解后我们就可以利用循环判断每一行的最大值是否是当前列的最小值

因为鞍点可能有很多个,所以要一边检索一边输出

代码如下

for(int i=1;i<=6;i++){
	if(ma[mi[i]]==i){
		printf("%d %d %d",mi[i],i,a[mi[i]][i]);
	}
}

题目中还有一种情况——没有鞍点,输出"not found"

So我们要在输出时定义一个判断变量,判断是否有鞍点

没有鞍点就是否 ( false ),检索到鞍点就改为是 ( true )

代码如下

bool z=false;
for(int i=1;i<=5;i++){
	if(ma[mi[i]]==i){
		z=true;
		cout<<mi[i]<<i<<a[mi[i]][i]<<endl;
	}
}
if(z==false)cout<<"not found";

最终整合

综上所述,再加上输入部分就大功告成了

#include<bits/stdc++.h>
using namespace std;
int a[6][6];
int ma[6],mi[6];
int main()
{
	for(int i=1;i<6;i++)
		for(int j=1;j<6;j++)
			cin>>a[i][j];
    for(int i=1;i<6;i++){
	    int maxn=a[i][1],minn=a[1][i];
        ma[i]=mi[i]=1;
    	for(int j=2;j<=5;j++){
    		if(a[i][j]>maxn){
	    		maxn=a[i][j];
		    	ma[i]=j;
    	    }
	    	if(a[j][i]<minn){
		    	minn=a[j][i];
			    mi[i]=j;
	    	}
    	}
    }
	bool z=false;
    for(int i=1;i<=5;i++){
       	if(ma[mi[i]]==i){
	    	z=true;
	    	cout<<mi[i]<<" "<<i<<" "<<a[mi[i]][i]<<endl;
	    }
    }
    if(z==false)cout<<"not found";
    return 0;
}

满分,再见

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值