C语言之求二维数组中的靶点

题目描述:如果矩阵 AA 中存在这样的一个元素 AijA_{ij} 满足条件 AijA_{ij} 是第 ii 行中值最小的元素,且又是第 jj 列中值最大的元素,则称之为该矩阵的一个马鞍点。请编程计算出 m×nm \times n 的矩阵 AA的马鞍点。

输入

3 3

1 7 3

5 4 6

17 18 9

#include<stdio.h>
int main()
{
	int i;
	int m,n;
	scanf("%d%d",&m,&n);
	int a[m][n];
	int j;
	for(i=0;i<m;i++){
		for(j=0;j<n;j++){
			scanf("%d",&a[i][j]);
		}
	}
	int p,s;
	for(i=0;i<m;i++){
		int min=a[i][0];
		p=0;
		for(j=0;j<n;j++){
			if(min>a[i][j]){
				min=a[i][j];
			    p=j;
			}
		}
		int is_saddle=1; 
		for(s=0;s<m;s++){
			if(min<a[s][p]){
		        is_saddle=0;
	        } 
		}
		if(is_saddle){
			printf("%d",min);
		}
	}
	return 0;
}

上述代码主要修改点:外循环是行数,一行一行找最小的数。

每次换行的时候都需要重新初始化最小值为第一个元素,否则上一行的最小值会影响到下一行。同时也要初始化p,可以在循环外面,也可以在循环里面,总之要初始化,否则会出现Segmentation fault的情况。只要是在if条件语句内的变量,最好都进行初始化,否则如果if条件不满足,会有垃圾值,会出现上述情况。

标志变量:

is_saddle=1是标志变量,用来表示当前判断的状态。假设当前元素是鞍点。工作原理:1.初始假设:假设当前元素,即第i行最小值是鞍点。

2.验证过程:检查该元素是否为所在其列的最大值。

3.可能推翻:如果不是最大值,就把它标志成0。

#include<stdio.h>
int main()
{
	int i;
	int m,n;
	scanf("%d%d",&m,&n);
	int a[m][n];
	int j;
	for(i=0;i<m;i++){
		for(j=0;j<n;j++){
			scanf("%d",&a[i][j]);
		}
	}
	int p,s;
	
	for(i=0;i<m;i++){
		int min=a[i][0];
		int max=a[i][0];
		for(j=0;j<n;j++){
			if(min>a[i][j]){
				min=a[i][j];
			    p=j;
			    max=a[i][j];
			}
		}
		for(s=0;s<m;s++){
			if(max<a[s][p]){
		        max=a[s][p];
	        } 
		}
		if(min==max){
			printf("%d",min);
		}
	}
	return 0;
}

 上述代码不对原因:只要当时判断的最小值在其这一列上不是最大值,就说明该最小值不是鞍点,不需要再进行最大值初始化,求出最大值,应该直接break;结束该过程。(上述应该是个判断,不是求值,不要理解错了)

for(s=0;s<m;s++){
	if(min<a[s][p]){
		break;
	}
}
if(s==m){//如果循环完整执行完,即这一列没有比这个最小值大的数,则该点即为鞍点。
	printf("%d",min);
}

上述代码是不利用标志变量求得鞍点。

posted @ 2025-12-02 16:53  代码无bug抓狂者  阅读(0)  评论(0)    收藏  举报