poj 3685 Matrix
Posted ZefengYao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 3685 Matrix相关的知识,希望对你有一定的参考价值。
Matrix
Time Limit: 6000MS | Memory Limit: 65536K | |
Total Submissions: 6448 | Accepted: 1858 |
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
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列的元素Aij的值等于i
2
+ 100000 × i + j
2
- 100000 × j + i × j ,
要找到这个矩阵元素中第k小的元素。
思路:可以发现对于矩阵的每一行或者每一列的所有元素而言,元素值的变化都是单调的,我们选其一,讨论每一列的元素,每一列元素从上到下是单调递增的。
因此我们可以用两重的二分法解决该问题。第一重二分用于搜索第k小的元素的值,对于每一个找到的值,再用一次二分用于检验该值是否是第k小的元素。
故第一重二分的判断条件可以为C1:比该元素小的值是否小于k个,如果true,则真正要找的元素比当前元素可能还要大一点。
第二重二分判断条件C2:对于每一列分别进行判断,在每一列中分别找到比当前元素的小的元素的个数并累加之。总和即是第一重二分需要判断的比该元素小的元素的个数
AC代码:
#define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<algorithm> #include<numeric> #include<cstring> using namespace std; typedef long long ll; const int N_MAX = 50000; ll n, m; ll f(const ll&i, const ll&j) { return (i*i + j*j + 100000 * i - 100000 * j + i*j); } bool C(const ll&mid) {//判断mid是不是第m小的值,false表示比mid小的数量大于等于m个,说明mid太大 ll smaller_num = 0; //比mid小的数必须正好有m-1个才行 for (int i = 1; i < n+1;i++) {//对于每一行而言,都要进行二分搜索,千万注意行列最好要从1取,计算元素值有用 int lb = 0, ub = n + 1; while (ub - lb > 1) { int mid2 = (ub + lb) >>1; if (f(mid2, i) < mid)lb=mid2; else ub = mid2; } smaller_num += lb; } return smaller_num < m; } int main() { int t; scanf("%d",&t); while (t--) { scanf("%lld%lld",&n,&m); ll lb = -100000*n,ub=3*n*n+100000*n; while (ub-lb>1) { ll mid = (lb + ub) >>1; if (C(mid))lb = mid;//[lb,ub) else ub = mid; } printf("%lld\n",lb); } return 0; }
以上是关于poj 3685 Matrix的主要内容,如果未能解决你的问题,请参考以下文章