POJ - 3685 Matrix(二分/查找第k大值)
2017-04-26 23:24
302 查看
问题描述
Given a N × N matrix A, whose element in the i-th row and j-th column Aij is an number that equals i^2 + 100000 × i + j^2 - 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
分析一下这个式子i^2 + 100000 × i + j^2 - 100000 × j + i × j
我们发现如果定j的话,式子随着i单调递增,那么这样就可以先循环j,内部用二分i来统计小于d的共有多少个数,然后最后判断是否小于M,小于M就是d弄的小了。二分套二分
Given a N × N matrix A, whose element in the i-th row and j-th column Aij is an number that equals i^2 + 100000 × i + j^2 - 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
分析:
这个问题也是典型的查找第k大值,所以依然用二分法,和POJ-3579这题有着异曲同工之处。分析一下这个式子i^2 + 100000 × i + j^2 - 100000 × j + i × j
我们发现如果定j的话,式子随着i单调递增,那么这样就可以先循环j,内部用二分i来统计小于d的共有多少个数,然后最后判断是否小于M,小于M就是d弄的小了。二分套二分
#include<cstdio> #include<algorithm> using namespace std; typedef long long ll; ll N,M; ll f(ll i, ll j) { return i * i + 100000 * i + j * j - 100000 * j + i * j; } bool C(ll d) { ll cnt = 0; for(int j=1; j<N+1; j++) { ll lb = 0, ub = N+1; while(ub - lb > 1) { ll i = (ub + lb) / 2; if(f(i, j) < d) { lb = i; 4000 } else ub = i; } cnt += lb; } return cnt < M; } void solve() { ll lb = -100000*N, ub = N * N + 100000 * N + N * N + N * N; while(ub - lb > 1) { ll mid = (lb + ub) / 2; if(C(mid)) lb = mid; else ub = mid; } printf("%lld\n", lb); } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&N, &M); solve(); } return 0; }
相关文章推荐
- POJ_3685_Matrix_(二分,查找第k大的值)
- 【POJ】3685 - Matrix 二分->查找第K大的值
- poj 3685 Matrix(二分搜索之查找第k大的值)
- POJ - 3685 Matrix (二分搜索:查找第k大的值)
- POJ 3685 Matrix 二分求解第K大
- POJ 3579 3685(二分-查找第k大的值)
- poj 3685(二分查找第K大的值)
- POJ_3579_Median_(二分,查找第k大的值)
- POJ 3685 Matrix 详细题解 (二分嵌套)
- POJ - 3685 Matrix(二分)
- poj 3685 Matrix (二分套二分)
- 二分-poj-3685-Matrix
- POJ 3685:Matrix 二分
- poj 3579 Median (二分搜索之查找第k大的值)
- POJ3685 Matrix (二分-查找第K大的值)
- POJ 3685:Matrix 二分
- poj 3685 Matrix 二分里套二分
- POJ 3685 Matrix 二分 函数单调性 难度:2
- 《挑战程序设计竞赛》3.1.3 二分搜索-查找第k大的值 POJ3579 3685
- poj 3685 Matrix(二分嵌套)