题目链接:http://219.244.176.199/JudgeOnline/problem.php?id=1214

这是这次微软实习面试的一道题,题目大意就是:有一个n*m的矩阵,已知它每一行都是不严格递增的,而且每一行的任意数都比前一行的任意数大或等于。给你一个数k,请你判断k是否存在于矩阵中。

当时想到的方法是二分第一列,就能确定k位于哪一行,然后二分这一行,得到是否存在k。二分第一列的复杂度是O(logn),二分那一行的复杂度是O(logm),所以总的复杂度是O(logn+logm)。

不过上面的写法需要写两个二分。其实二维数组在内存中是连续的一段内存,所以我们可以直接把二维数组看成一个一维数组b,那么b[p]对应的就是a[p/m][p%m]。这样的话就可以直接进行一维数组的二分了。复杂度是O(logmn)。

其实两个的时间复杂度是一致的,只是写法第二种稍微简单一点。

代码:二分+二分

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <string>
#define LL long long using namespace std; int a[][];
int n, m, q; void input()
{
for (int i = ; i < n; ++i)
for (int j = ; j < m; ++j)
scanf("%d", &a[i][j]);
} bool binSearch(int k)
{
int lt = , rt = n-, mid, row;
while (lt+ < rt)
{
mid = (lt+rt)>>;
if (a[mid][] <= k) lt = mid;
else rt = mid;
}
if (a[rt][] <= k) row = rt;
else row = lt; lt = ; rt = m-;
while (lt+ < rt)
{
mid = (lt+rt)>>;
if (a[row][mid] <= k) lt = mid;
else rt = mid;
}
if (a[row][lt] == k) return true;
if (a[row][rt] == k) return true;
return false;
} void work()
{
int k;
scanf("%d", &q);
for (int i = ; i < q; ++i)
{
scanf("%d", &k);
if (binSearch(k)) printf("Yes\n");
else printf("No\n");
}
} int main()
{
//freopen("test2.in", "r", stdin);
//freopen("test3.out", "w", stdout);
while (scanf("%d%d", &n, &m) != EOF)
{
input();
work();
} return ;
}

代码:看成一维二分

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <string>
#define LL long long using namespace std; int a[][];
int n, m, q; void input()
{
for (int i = ; i < n; ++i)
for (int j = ; j < m; ++j)
scanf("%d", &a[i][j]);
} bool binSearch(int k)
{
int lt = , rt = n*m-, mid;
while (lt+ < rt)
{
mid = (lt+rt)>>;
if (a[mid/m][mid%m] <= k) lt = mid;
else rt = mid;
}
if (a[lt/m][lt%m] == k) return true;
if (a[rt/m][rt%m] == k) return true;
return false;
} void work()
{
int k;
scanf("%d", &q);
for (int i = ; i < q; ++i)
{
scanf("%d", &k);
if (binSearch(k)) printf("Yes\n");
else printf("No\n");
}
} int main()
{
//freopen("test2.in", "r", stdin);
//freopen("test3.out", "w", stdout);
while (scanf("%d%d", &n, &m) != EOF)
{
input();
work();
} return ;
}

ACM学习历程—SNNUOJ1214 矩阵1(二分)的更多相关文章

  1. ACM学习历程—SNNUOJ1215 矩阵2(二分 && dfs)

    http://219.244.176.199/JudgeOnline/problem.php?id=1215 这是这次微软和百度实习面试的一道题,题目大意就是:有一个n*m的矩阵,已知它每一行都是不严 ...

  2. ACM学习历程—HDU5667 Sequence(数论 && 矩阵乘法 && 快速幂)

    http://acm.hdu.edu.cn/showproblem.php?pid=5667 这题的关键是处理指数,因为最后结果是a^t这种的,主要是如何计算t. 发现t是一个递推式,t(n) = c ...

  3. ACM学习历程—HDU5592 ZYB's Premutation(逆序数 && 树状数组 && 二分)(BestCoder Round #65 1003)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5592 题目大意就是给了每个[1, i]区间逆序对的个数,要求复原原序列. 比赛的时候2B了一发. 首先 ...

  4. ACM学习历程—HDU5587 Array(数学 && 二分 && 记忆化 || 数位DP)(BestCoder Round #64 (div.2) 1003)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5587 题目大意就是初始有一个1,然后每次操作都是先在序列后面添加一个0,然后把原序列添加到0后面,然后 ...

  5. ACM学习历程—UESTC 1222 Sudoku(矩阵)(2015CCPC H)

    题目链接:http://acm.uestc.edu.cn/#/problem/show/1226 题目大意就是构造一个行列和每个角的2*2都是1234的4*4矩阵. 用dfs暴力搜索,不过需要每一步进 ...

  6. ACM学习历程—UESTC 1215 Secrete Master Plan(矩阵旋转)(2015CCPC A)

    题目链接:http://acm.uestc.edu.cn/#/problem/show/1215 题目大意就是问一个2*2的矩阵能否通过旋转得到另一个. 代码: #include <iostre ...

  7. ACM学习历程—51NOD 1685 第K大区间2(二分 && 树状数组 && 中位数)

    http://www.51nod.com/contest/problem.html#!problemId=1685 这是这次BSG白山极客挑战赛的E题. 这题可以二分答案t. 关键在于,对于一个t,如 ...

  8. ACM学习历程—Hihocoder 1139 二分·二分答案(bfs)

    http://hihocoder.com/problemset/problem/1139 这题提示上写的是二分,但是感觉不二分应该也可以,至少题目是AC的... 二分的思想就是二分答案的值,看能不能在 ...

  9. ACM学习历程—Hihocoder 1288 Font Size(暴力 || 二分)

    http://hihocoder.com/problemset/problem/1288 这题是这次微软笔试的第一题,关键的是s的上限是min(w, h),这样s的范围只有到1000,这样就可以直接暴 ...

随机推荐

  1. 基于linux的ekho(余音)安装与开发

    Ekho(余音)是一个把文字转换成声音的软件.它目前支持粤语.普通话(国语).诏安客语和韩语(试验中),英文则通过Festival间接实现.它比eSpeak的设计更简易,但文件较大.由于使用了真人发声 ...

  2. Java虚拟机的平台无关性与语言无关性

    平台无关性 不同平台的不同java虚拟机,都执行同一种字节码文件,即Class文件 语言无关性 Java虚拟机不止能执行java程序,还有Clojure.Groovy.JRuby.Jython.Sca ...

  3. React Native的生命周期解析

    在React Native中使用组件来封装界面模块时,整个界面就是一个大的组件,开发过程就是不断优化和拆分界面组件.构造整个组件树的过程. 上张图涵盖了一个组件从创建.运行到销毁的整个过程.大家可以看 ...

  4. CentOS 7 导入epel库

    yum install epel-release 或者到百度云下载相应的 rpm 包进行安装 rpm -ivh epel-release-7-9.noarch.rpm

  5. 【简单dp】poj 1458 最长公共子序列【O(n^2)】【模板】

    最长公共子序列可以用在下面的问题时:给你一个字符串,请问最少还需要添加多少个字符就可以让它编程一个回文串? 解法:ans=strlen(原串)-LCS(原串,反串); Sample Input abc ...

  6. C++中容器的使用(二)

    第一章容器 第1条:慎重选择容器类型. 标准STL序列容器:vector.string.deque和list. 标准STL关联容器:set.multiset.map和multimap. 非标准序列容器 ...

  7. java 反射机制复习笔记。

    1.java 反射的作用(好处): (1)能够使我们很方便的创建灵活的代码,这些代码可以在运行时装配(运行时获取一个类实例),就不用在组件之间进行源代码链接了,大大提高系统的灵活性和扩展性. (2)与 ...

  8. HBase-存储-写路径

    写路径 当用户向HRegionServer发起put请求时,其会将请求交给对应的HRegion实例来处理.第一步是要决定数据是否需要写到由HLog类实现的预写日志中.WAL是标准的Hadoop Seq ...

  9. Apache Phoenix基本操作-2

    1. 如何映射一个Phoenix的表到一个Hbase的表? 你可以通过Create table/create view DDL语句在一个已经存在的hbase表上创建一个Phoenix表或者视图.对于C ...

  10. OpenStack日志搜集分析之ELK

    ELK 安装配置简单,用于管理 OpenStack 日志时需注意两点: Logstash 配置文件的编写 Elasticsearch 日志存储空间的容量规划 另外推荐 ELKstack 中文指南. E ...