• POJ 3685


    Matrix
    Time Limit: 6000MS   Memory Limit: 65536K
    Total Submissions: 4428   Accepted: 1102

    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
    

    Source

     
    首先二分第m小的数,由公式易得每列的数是按照从小到大排列的,因此可二分,两次二分即可。
     
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 
     6 using namespace std;
     7 
     8 typedef long long ll;
     9 
    10 int n;
    11 ll m;
    12 
    13 ll cal(ll i,ll j) {
    14         return i * i + j * j + (i - j) * 100000 + i * j;
    15 }
    16 
    17 bool judge(ll x) {
    18         ll sum = 0;
    19         for(int j = 1; j <= n; ++j) {
    20                 int l = 0,r = n;
    21                 while(l < r){
    22                         int mid = (l + r + 1) / 2;
    23                         if(cal(mid,j) <= x) {
    24                                 l = mid;
    25                         } else {
    26                                 r = mid - 1;
    27                         }
    28                 }
    29                 sum += l;
    30         }
    31 
    32         return sum >= m;
    33 
    34 }
    35 
    36 void solve() {
    37         ll l = -1e12,r = 1e12;
    38 
    39         //printf(" n = %d l = %lld r = %lld
    ",n,l,r);
    40 
    41         while(l < r) {
    42                 ll mid = (l + r) >> 1;
    43                 if(judge(mid)) r = mid;
    44                 else l = mid + 1;
    45         }
    46 
    47 
    48 
    49       printf("%I64d
    ",l);
    50 }
    51 
    52 int main() {
    53        // freopen("sw.in","r",stdin);
    54 
    55         int t;
    56         scanf("%d",&t);
    57 
    58         while(t--) {
    59                 scanf("%d%I64d",&n,&m);
    60                 solve();
    61         }
    62 
    63         return 0;
    64 }
    View Code
  • 相关阅读:
    多线程编程(一)
    所谓费曼学习法
    Java 基本数据类型扩充
    好记性不如烂笔头
    Java_面试札记
    Stream替代for-编码五分钟-划水五小时
    为什么启动线程是start方法?
    Java面试札记
    Tree
    手写SpringMVC 框架
  • 原文地址:https://www.cnblogs.com/hyxsolitude/p/3612242.html
Copyright © 2020-2023  润新知