poj3685 Matrix(第K大的数)

题意:给你一个公式,i行,j列,表示这个矩阵里i行j列的数是i^2 + 100000 × i + j^2 - 100000 × j + i × j.
求这个矩阵第m大的数。
思路:数学差的看不出这个公式的规律,可以先输出几行发现,每列从上往下递增,从左往右递增。
所以这个二分的判断函数里面也是二分查找比x小的个数,在进行判断。
详细见代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll n,m;
ll cal(ll i,ll j){
  return i*i+100000*i+j*j-100000*j+i*j;
}
bool check(ll x)
{
    ll num=0;
    for(int j=n;j>=1;j--){
        if(cal(1,j)>x) break;//剪枝,由于从左往右的列,依次递增,同时每行依次递增,所以如果第一个就大于x,以后就不用找了,都是大于x. 
        int l=1,r=n;
        while(l<=r){
            int mid=(l+r)/2;
            if(cal(mid,j)<x) l=mid+1;
            else r=mid-1;
        }
        num+=(l-1);
    }
    return num>=m;
}

int main()
{
    int T;scanf("%d",&T);
    while(T--){
       scanf("%lld %lld",&n,&m);
       ll l=-100000*n,r=n*n*3+100000*n;
       while(l<=r){
          ll mid=l+(r-l)/2;
          if(!check(mid)) l=mid+1;
          else r=mid-1;
       }
       printf("%lld\n",l-1);
    }
}

你可能感兴趣的:(poj3685 Matrix(第K大的数))