杨氏矩阵的查找

题目描述

杨氏矩阵,即在一个二维数组中,每一行都按照从左到右严格递增的顺序排序,每一列都按照从上到下严格递增的顺序排序。请完成一个函数,输入这样的一个N*N的二维数组和M个整数,判断数组中是否含有上述M个整数。你能解决这个问题吗?

输入格式

可能有多个测试输入,第一行给出总共的测试输入的个数。

对于每个测试输入,第一行包含两个正整数N和M,接下来是一个N*N的杨氏矩阵,最后是M个待查找的整数(0<N<1000,0<M<10000)。

输出格式

对于每一个待查找的整数,输出true或false,即判断矩阵中是否含有该整数。

样例输入
1
5 3
1 5 10 15 20
2 7 13 18 24
3 9 15 21 28
4 12 20 28 32
5 15 24 30 35
15
31
35

样例输出
true
false
true


解法1:
最基本的思路就是使用一个二维数组来储存矩阵,然后遍历矩阵后得出相对应的结果,这样做的话效率是十分低的。
解法2:
这里介绍另外一种较为取巧的算法。先开辟一个较大的一维数组a[100000],然后让数组中的元素都初始化为0,在开始输入矩阵的时候,将矩阵数值作为一维数组的下标,此下标所对应的数组值赋为1。比如输入矩阵中的一个值为b,则执行操作a[b] = 1。如果要检索c在不在矩阵中,只需要判断a[c]是否等于1即可。


两种解法的具体代码如下:

解法1:
//Made by Xu Lizi
//2013-10-30
#include <stdio.h>

int main () {
    int T;
    scanf ("%d", &T);
    while (T--) {
          int N, M;
          scanf ("%d%d", &N, &M);
          int a[N][N], b;
          for (int i = 0; i < N; i++) {
              for (int j = 0; j < N; j++) {
                  scanf ("%d", &a[i][j]);
              }
          }          
          while (M--) {
                  scanf ("%d", &b);
                  for (int  j = 0, k = 0; ;) {
                        if (b > a[N-1][N-1] || b < a[0][0]) {
                             printf ("false\n");
                             break;
                        } 
                        if (b == a[j][k]) {
                             printf ("true\n");
                             break;
                        }
                        if ( j >= N || k >= N || (b < a[j][k+1] && b < a[j+1][k])) {
                             printf ("false\n");
                             break;
                        }                 
                        if (b >= a[j][k+1]) k++;
                        if (b >= a[j+1][k]) j++;    
                  }        
          }
    }

    return 0;
}                      


解法2:
//Made by Xu Lizi
//2013-10-30
#include <stdio.h>

int main () {
    int T;
    scanf ("%d", &T);
    while (T--) {
          int N, M;
          scanf ("%d%d", &N, &M);
          int a[100000] = {0}, b, entry, max = 0;
          for (int i = 0; i < N*N; i++) {              
               scanf ("%d", &entry);
               a[entry] = 1;
               if (max < entry) max = entry;
          }        
          while (M--) {
                  scanf ("%d", &b);
                  if (a[b] == 1) {
                        printf ("true\n");
                  } else {
                        printf ("false\n");
                  }                                   
          }
    }

    return 0;
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值