ACM学习历程—SNNUOJ1214 矩阵1(二分)
题目链接: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(二分)的更多相关文章
- ACM学习历程—SNNUOJ1215 矩阵2(二分 && dfs)
http://219.244.176.199/JudgeOnline/problem.php?id=1215 这是这次微软和百度实习面试的一道题,题目大意就是:有一个n*m的矩阵,已知它每一行都是不严 ...
- ACM学习历程—HDU5667 Sequence(数论 && 矩阵乘法 && 快速幂)
http://acm.hdu.edu.cn/showproblem.php?pid=5667 这题的关键是处理指数,因为最后结果是a^t这种的,主要是如何计算t. 发现t是一个递推式,t(n) = c ...
- ACM学习历程—HDU5592 ZYB's Premutation(逆序数 && 树状数组 && 二分)(BestCoder Round #65 1003)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5592 题目大意就是给了每个[1, i]区间逆序对的个数,要求复原原序列. 比赛的时候2B了一发. 首先 ...
- ACM学习历程—HDU5587 Array(数学 && 二分 && 记忆化 || 数位DP)(BestCoder Round #64 (div.2) 1003)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5587 题目大意就是初始有一个1,然后每次操作都是先在序列后面添加一个0,然后把原序列添加到0后面,然后 ...
- ACM学习历程—UESTC 1222 Sudoku(矩阵)(2015CCPC H)
题目链接:http://acm.uestc.edu.cn/#/problem/show/1226 题目大意就是构造一个行列和每个角的2*2都是1234的4*4矩阵. 用dfs暴力搜索,不过需要每一步进 ...
- ACM学习历程—UESTC 1215 Secrete Master Plan(矩阵旋转)(2015CCPC A)
题目链接:http://acm.uestc.edu.cn/#/problem/show/1215 题目大意就是问一个2*2的矩阵能否通过旋转得到另一个. 代码: #include <iostre ...
- ACM学习历程—51NOD 1685 第K大区间2(二分 && 树状数组 && 中位数)
http://www.51nod.com/contest/problem.html#!problemId=1685 这是这次BSG白山极客挑战赛的E题. 这题可以二分答案t. 关键在于,对于一个t,如 ...
- ACM学习历程—Hihocoder 1139 二分·二分答案(bfs)
http://hihocoder.com/problemset/problem/1139 这题提示上写的是二分,但是感觉不二分应该也可以,至少题目是AC的... 二分的思想就是二分答案的值,看能不能在 ...
- ACM学习历程—Hihocoder 1288 Font Size(暴力 || 二分)
http://hihocoder.com/problemset/problem/1288 这题是这次微软笔试的第一题,关键的是s的上限是min(w, h),这样s的范围只有到1000,这样就可以直接暴 ...
随机推荐
- hadoop01
RPC:异步系统的调用,webservice是RPC的一种.webservice用于不在同一个公司的系统调用,同一个公司用socket调用.就是RPC. Dubbo淘宝的RPC框架. Hadoop r ...
- yii常用操作函数
<?php defined('YII_DEBUG') or define('YII_DEBUG', true); //当在调试模式下,应用会保留更多日志信息,如果抛出异常,会显示详细的错误调用堆 ...
- Android开发BUG及解决方法1
错误描述: 问题1: Error:Execution failed for task ':app:transformClassesWithDexForDebug'. > com.Android. ...
- ETL应用:使用Pro*C写入文件信息入库的方法
ETL处理过程中,经常需要进行文件校验,如文件级校验.记录级校验,需要保存文件的基本信息,文件名.文件大小.数据日期等,使用Pro*C的一种方法如下: #include <stdio.h> ...
- 【鸟哥的Linux私房菜】笔记2
Linux的应用 学习资源整理 安装记录 >< 1.Linux的应用: 网络服务器 数据库 学术机构的高效运算任务 嵌入式系统 ... 2.挂载与磁盘分区 学习资源整理 学习 1.书上的网 ...
- Docker容器技术-命令进阶
一.基本命令 1.Docker布尔型选项 使用某选项但没有提供参数,等同于把选项设置为true,要改变它的值,唯一的方法是将其设置成false. 找出一个选项的默认值是true还是false: [ro ...
- CSS3带小图标垂直下拉菜单
在线演示 本地下载
- 读完这篇文章,就基本搞定了Redis数据库
简单来说Redis就是一个数据库,不过与传统的数据库不同的是Redis的数据是存在内存中的,所以存写速度非常快,因此Redis被广泛应用于缓存方向. 另外,Redis也经常用来做分布式锁.Redis提 ...
- Python的format函数
Python的format函数 自python2.6开始,新增了一种格式化字符串的函数str.format(),此函数可以快速处理各种字符串. 语法 它通过{}和:来代替%. 请看下面的示例,基本上总 ...
- block(data block,directory block)、inode、块位图、inode位图和super block概念详解【转】
本文转载自:https://blog.csdn.net/jhndiuowehu/article/details/50788287 一.基本概念: 1.block:文件系统中存储数据的最小单元 ...