二维数组的查找
Time Limit: 2000/1000ms (Java/Others)
Problem Description:
给定一个n*m的二维数组,保证a[i][j] < a[i+1][j],a[i][j]< a[i][j+1](其中0≤i< n-1,0≤j< m-1); 接下来有q个询问,每个询问包含一个数字num,查找num是否包含在该二维数组里面。
Input:
输入包含多组测试数据,对于每组数据,首先输入两个整数n,m,(1≤n,m≤1000).接下来输入n*m个数a[i][j](0≤a[i][j]≤10^9);接下来有q(1≤q≤1000)个询问每个询问包含一个数字num。
Output:
对于每组数据,对于每个询问如果num在二维数组里,输出Yes,否则输出No。
Sample Input:
4 3 1 2 8 2 4 9 4 7 10 6 8 11 3 5 4 10
Sample Output:
No Yes Yes解题思路:二维数组的查找,题目中给出的矩阵最大为10^3*10^3,暴力查找显然会超时。但解题的关键在于标红色的条件,即每一行是升序,每一列也是升序,所以根据这个特点,查找的起始点应从右上角开始,向左边和下边进行扫描比较,这样可以节省很多时间。①显然当a[i][j]>num时,说明当前行num可能在当前行,于是j--向左扫描;②当a[i][j]<num时,说明当前行所在列的值比较小,于是i++进入下一行进行比较,③最后相等时,只需做一个标记看是否矩阵中存在这个元素即可。这里可能对②这种情况会有疑问,我们简单拿3*3矩阵举个栗子:3 6 -- 11 |4 7 12 |5 8 13如果我们要查找元素9是否在矩阵中,首先11>9,于是--j,然后6<9,于是++i,解决疑问就在这里,因为11所在列是升序,即11<12,所以当num>a[i][j](9>6)++i之后,即现在第二行所在列(比如:12)之后肯定比num大,所以不用去比较剩下的列元素。当9与8比较完之后,由于9>8,所以++i导致越界,于是退出循环,表示矩阵中没有9这个元素。AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int a[1005][1005],n,m,q,num;bool flag;//标记是否找到 4 int main() 5 { 6 while(cin>>n>>m){ 7 for(int i=0;i<n;++i) 8 for(int j=0;j<m;++j) 9 cin>>a[i][j]; 10 cin>>q; 11 while(q--){ 12 cin>>num;flag=false; 13 for(int i=0,j=m-1;!flag && i<n && j>=0;){ 14 if(a[i][j]==num)flag=true; 15 else if(a[i][j]<num)++i; 16 else --j; 17 } 18 if(flag)cout<<"Yes"<<endl; 19 else cout<<"No"<<endl; 20 } 21 } 22 return 0; 23 }
原文地址:https://www.cnblogs.com/acgoto/p/9031435.html
时间: 2024-10-31 22:43:57