POJ 3685:Matrix 二分
2015-10-29 11:41
295 查看
Matrix
Description
Given a N × N matrix A, whose element in the i-th row and j-th column Aij is an number that equals i2 + 100000 × i + j2 - 100000 × j + i × j,
you are to find the M-th smallest element in the matrix.
Input
The first line of input is the number of test case.
For each test case there is only one line contains two integers, N(1 ≤ N ≤ 50,000) and M(1 ≤ M ≤ N × N). There is a blank line before each test case.
Output
For each test case output the answer on a single line.
Sample Input
Sample Output
给了一个N*N的矩阵,每个位置上的数由该位置的下标i,j决定。然后问这个矩阵中第m小的数。
通过这道题好好总结了一下二分,总算是深刻理解了一下。
第一个二分枚举答案,第二个二分,通过公式可知,函数跟j不是单调的关系,但跟i是单调的关系,所以每次枚举j,然后二分i的值。
代码:
Time Limit: 6000MS | Memory Limit: 65536K | |
Total Submissions: 5489 | Accepted: 1511 |
Given a N × N matrix A, whose element in the i-th row and j-th column Aij is an number that equals i2 + 100000 × i + j2 - 100000 × j + i × j,
you are to find the M-th smallest element in the matrix.
Input
The first line of input is the number of test case.
For each test case there is only one line contains two integers, N(1 ≤ N ≤ 50,000) and M(1 ≤ M ≤ N × N). There is a blank line before each test case.
Output
For each test case output the answer on a single line.
Sample Input
12 1 1 2 1 2 2 2 3 2 4 3 1 3 2 3 8 3 9 5 1 5 25 5 10
Sample Output
3 -99993 3 12 100007 -199987 -99993 100019 200013 -399969 400031 -99939
给了一个N*N的矩阵,每个位置上的数由该位置的下标i,j决定。然后问这个矩阵中第m小的数。
通过这道题好好总结了一下二分,总算是深刻理解了一下。
第一个二分枚举答案,第二个二分,通过公式可知,函数跟j不是单调的关系,但跟i是单调的关系,所以每次枚举j,然后二分i的值。
代码:
#include <iostream> #include <algorithm> #include <cmath> #include <vector> #include <string> #include <cstring> #pragma warning(disable:4996) using namespace std; #define maxn 1e12 typedef long long ll; ll m, n; ll le, ri, mid; ll cal(ll i, ll j) { return i*i + 100000 * i + j*j - 100000 * j + i*j; } ll check(ll x) { ll i, le, ri, mid, cnt; ll temp; cnt = 0; for (i = 1; i <= n; i++) { le = 1;//mid不能取到0,所以这里的le取1 ri = n + 1;//因为mid可能要取到n,所以这里的ri要取到比n大的数 mid = le + (ri - le) / 2; while (le < ri) { temp = cal(mid, i); if (cal(mid, i) < x) { le = mid + 1; } else { ri = mid ; } mid = le + (ri - le) / 2; } cnt += (mid - 1);//经过计算,这里始终是多计算了一个1,所以要在这里把它扣掉 } return cnt; } int main() { //freopen("i.txt", "r", stdin); //freopen("o.txt", "w", stdout); int test; scanf("%d", &test); while (test--) { scanf("%lld%lld", &n, &m); le = -maxn; ri = maxn; mid = le + (ri - le) / 2; while (le < ri) { if (check(mid) < m)//检查小于 mid 的个数 { le = mid + 1; } else { ri = mid; } mid = le + (ri - le) / 2; } printf("%lld\n", mid-1);//有m个小于mid的数,所以第m大的数就是mid-1 } //system("pause"); return 0; }
相关文章推荐
- Cloudera Hue 忘记超级用户密码解决方法
- IOS-22-XMPP(1)官方demo登录报错:iPhoneXMPPAppDelegate: xmppStream:didNotAuthenticate:
- python列表解析
- POJ 3685:Matrix 二分
- JSP针对表单重复提交的处理方法
- Linux系统上安装slurm来监控网络带宽和控制节点
- ICS学习——1——计算机系统漫游——(From:TJU章亦葵教授的课程《计算机组成原理》)
- 学习笔记 const(部分转载)
- 学会使用Event Review 做troubleshooting
- Android实战简易教程-第七十枪(自定义实用控制之-邮箱验证EditText)
- 海尔T520智能扫地机器人使用评测
- Android中的“再按一次返回键退出程序”实现
- ocderforce 583B Robot's Task(模拟)
- 设置自定义UITableViewCell之间的间距
- 浅谈Android应用性能之内存
- 收藏的兼容各浏览器的日历控件(ie6-11\ff\google\safri)
- 如何防止参数中的实体对象被修改
- C语言文法定义与C程序的推导过程
- 1014 C语言文法定义与C程序的推导过程
- 文法分析2