1104: 找鞍点(2级)
- 题目描述
在微分方程中,沿着某一方向是稳定的,另一条方向是不稳定的奇点,叫做鞍点。在泛函中,既不是极大值点也不是极小值点的临界点,叫做鞍点。在矩阵中,一个数在所在行中是最大值,在所在列中是最小值,则被称为鞍点。在物理上要广泛一些,指在一个方向是极大值,另一个方向是极小值的点。编写一个程序,找出n×m的矩阵a的鞍点,若存在必唯一,不存在则输出“Not Found”。
输入
有多行。第1行是两个整数n(n≤10)和m(m≤10),表示矩阵有n行m列。接下来n行,每行包含m个整数,表示矩阵值。
输出
仅一行。如果鞍点存在,则按指定格式输出鞍点;否则,输出“Not Found”。
样例输入 Copy
3 4
1 2 13 4
7 8 10 6
3 5 9 7
样例输出 Copy
a[2][2]=9
来源/分类
C语言程序设计练习题
该思路是找出每行最大值,每列最小值分别存入两个数组中,遍历数组如果某个元素等于指定行max数组且等于max数组指定列,则找到输出。
- 代码
cpp
#include<bits/stdc++.h>
using namespace std;
int main() {
int n,m;
cin>>n>>m;
int a[11][11];
int max[11]; //存放行最大
int min[11]; //存放列最小
memset(min,1000000,sizeof(min));
memset(max,-1000000,sizeof(max)); //将数组初始化为可供判断最值的形式
int flag=n; //用来判断是否找到鞍点
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
cin>>a[i][j]; //输入数组
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(a[i][j]>max[i]) //如果是行最大
max[i]=a[i][j]; //给数组该位置赋值
for(int j=0;j<m;j++)
for(int i=0;i<n;i++)
if(a[j][i]<min[j]) //如果是列最小
min[j]=a[i][j]; //给数组该位置赋值
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(a[i][j]==max[i] && a[i][j]==min[j]) //如果同时是行最大和列最小
{
printf("a[%d][%d]=%d\n",i,j,a[i][j]); //格式化输出坐标和值
flag--; //计数器减1
}
if(flag==n) //如果鞍点存在,则按指定格式输出鞍点;否则,输出“Not Found”。
cout<<"Not Found";
return 0;
}
但是只能通过样例和40%的测试数据。
python
n,m=map(int,input().split())
l=[]
for i in range(n):
l.append(list(map(int,input().split())))
maxh=[]
for i in range(n):
maxh.append(max(l[i]))
lie=[]
#将矩阵列存起来---------------
for i in range(m):
lie.append([])
j=0
while j<m:
for i in range(n):
lie[j].append(l[i][j])
j+=1
#-----------------------------
minl=[]
for k in range(m):
minl.append(min(lie[k]))
for i in range(n):
for j in range(m):
if (maxh[i]==minl[j]):
print("a[%d][%d]=%d"%(i,j,maxh[i]))
Python思路一样,结果也他喵的一样40%。
C(网友的思路)
#include<stdio.h>
int matrix[11][11],vis[11][11];
int main(){
int n,m,i,j;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{scanf("%d",&matrix[i][j]);} //常规读入矩阵
for(i=0;i<n;i++)
{
int max_num=matrix[i][0]; //假定每一行第一个是最大值
for(j=0;j<m;j++) //这层循环得出行最大值
{if(max_num<matrix[i][j]) max_num=matrix[i][j];}
for(j=0;j<m;j++) //这层循环得出行最大值位置
{if(max_num==matrix[i][j]) vis[i][j]=1;}
}
int flag=0;
for(j=0;j<m;j++){
int min_num=matrix[0][j];
for(i=0;i<n;i++) //与求行最大值同理求列最小值
{if(min_num>matrix[i][j]) min_num=matrix[i][j];}
for(i=0;i<n;i++) //下标重合说明鞍点找到
{if(min_num==matrix[i][j]&&vis[i][j]==1){
flag=1;
printf("a[%d][%d]=%d\n",i,j,matrix[i][j]);
}
}
}
if(!flag) printf("Not Found");
return 0;
}
csdn上看到的,更像是先找出行最大值位置,再用同样的方法找列最小值,跟行最大值位置比较,位置相同就对了。
所以为啥一个对一个不对,以后自然会懂的吧?