zoukankan      html  css  js  c++  java
  • POJ:3685-Matrix

    Matrix

    Time Limit: 6000MS Memory Limit: 65536K
    Total Submissions: 7879 Accepted: 2374

    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


    解题心得:

    1. 给你一个n * n的矩阵,矩阵一点的值是i^2 + 100000 × i + j^2 - 100000 × j + i × j,问在整个矩阵中第m大的值是多少。
    2. 刚开始分解组合这个表达式弄了半天发现没啥用,后来才发现这个表达式就是用来观察单调性的,当j不变的时候i是单调递增的,然后这样就可以按照有序性来进行二分了。
    3. 先枚举一个值(O(logn)),然后遍历每一列(O(n)),在每一列中二分查找比枚举的那个值小的有多少个(O(log(n))),这样总的时间复杂度就是O(n(logn)^2);

    #include <algorithm>
    #include <stdio.h>
    using namespace std;
    typedef long long ll;
    
    ll va(ll r, ll c){
        ll sum = r*r + 100000*r + c*c - 100000*c + r*c;
        return sum;
    }
    
    bool checke_col(ll ans,ll n,ll m) {
        ll num = 0;
        for(int j=1;j<=n;j++) {
            ll l = 0, r = n+1;
            while(r - l > 1) {
                ll mid = (l + r) >> 1;
                if(va(mid,j) < ans)
                    l = mid;
                else
                    r = mid;
            }
            num += l;
        }
        return num < m;
    }
    
    int main() {
        int t;
        scanf("%d",&t);
        while(t--) {
            ll n,m;
            scanf("%lld%lld",&n,&m);
            ll l = -100000*n, r = n*n + 100000*n + n*n + n*n;
            while(r - l > 1){
                ll mid = (l + r) / 2;
                if(checke_col(mid,n,m)) l = mid;
                else r = mid;
            }
            printf("%lld
    ",l);
        }
        return 0;
    }
    
  • 相关阅读:
    Ethical Hacking
    Ethical Hacking
    Ethical Hacking
    Ethical Hacking
    Ethical Hacking
    Ethical Hacking
    Oil Skimming HDU
    Rain on your Parade HDU
    Swap HDU
    棋盘游戏 HDU
  • 原文地址:https://www.cnblogs.com/GoldenFingers/p/9107119.html
Copyright © 2011-2022 走看看