zoukankan      html  css  js  c++  java
  • POJ 3685 Matrix (二分套二分)

    Matrix
    Time Limit: 6000MS   Memory Limit: 65536K
    Total Submissions: 8674   Accepted: 2634

    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 ≤ MN × 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
    

    Source

    POJ Founder Monthly Contest – 2008.08.31, windy7926778

    题意:定义矩阵中(i,j)位置的值为(i^2+j^2+i*j+100000*(i-j)

    求n*n矩阵中第m小的数

    题解:首先打表或者推式子发现列是单调递增的,所以可以考虑二分答案,对于每一列二分找到有几个数比他小,然后就可以nlogn作出总共有几个数比他小,然后就搞定了

    代码如下:

    #include<cmath>
    #include<cstdio>
    #include<cctype>
    #include<vector>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define lson ch[x][0]
    #define rson ch[x][1]
    #define hi puts("hi!");
    #define int long long
    using namespace std;
    
    int n,m;
    
    int get(int ith,int jth)
    {
        return ith*ith+100000ll*ith-100000ll*jth+jth*jth+ith*jth;
    }
    
    int find(int x,int jth)
    {
        int l=0,r=n,mid;
        while(l<=r)
        {
            mid=(l+r)>>1;
            if(get(mid,jth)<=x)
            {
                l=mid;
            }
            else
            {
                r=mid-1;
            }
            if(r-l<=1) 
            {
                if(get(r,jth)<=x) mid=r;
                else mid=l;
                break;
            }
        }
        return mid;
    }
    
    int check(int x)
    {
        int cnt=0;
        for(int i=1;i<=n;i++)
        {
            cnt+=find(x,i);
        }
        if(cnt>=m) return 1;
        else return 0;
    }
    
    signed main()
    {
        int ttt;
        scanf("%lld",&ttt);
        while(ttt--)
        {
            int ans;
            scanf("%lld%lld",&n,&m);
            int l=-1e12,r=1e12,mid;
            while(l<=r)
            {
                mid=(l+r)>>1;
                if(check(mid))
                {
                    ans=mid;
                    r=mid-1;
                }
                else
                {
                    l=mid+1;
                }
            }
            printf("%lld
    ",ans);
        }
    }
  • 相关阅读:
    Ubuntu 17.10 联网、jdk配置、初始化
    记一次与为知笔记的客服沟通
    C++ Primer zh 5th 思维导图
    《程序员健康指南(The Healthy Programmer)》笔记
    Learn_OpenGL_002_你好,长方形
    Learn_OpenGL_001_环境配置
    Visual Studio Community 2017 配置 OpenGL 环境
    oracle删除数据库
    oracle修改审计功能
    dataguard日志自动删除
  • 原文地址:https://www.cnblogs.com/stxy-ferryman/p/9626431.html
Copyright © 2011-2022 走看看