poj3685Matrix(二分)

来源:互联网 发布:电脑监控器软件 编辑:程序博客网 时间:2024/05/16 02:06

看到题完全没想到是二分(太弱,太渣了),别人告诉本弱这道题是二分依旧不会做。
思路:二分答案ans,然后枚举j,然后再二分i,求出矩阵中小于等于ans元素的个数……
注意二分时如果l或r出现负数,最好直接向下取整,否则如(-1+0)/2=0,本来是想让他等于-1的,这样就可能进入死循环。

#include <iostream>#include <stdio.h>#include <algorithm>#include <stdlib.h>#include <stack>#include <vector>#include <string.h>#include <math.h>#include <queue>#define msc(X) memset(X,-1,sizeof(X))#define ms(X) memset(X,0,sizeof(X))typedef long long LL;using namespace std;const LL inf=1ll<<33;#define f(X,Y) ((X)*(X)+100000*(X)+(Y)*(Y)-100000*(Y)+(X)*(Y))const double eps=1e-5;int n;LL m;bool judge(LL num){    LL cnt=0;    for(int j=1;j<=n;j++)    {        int l=1,r=n+1,mid;        while(l<r){            mid=(l+r)>>1;            if(f((LL)mid,(LL)j)>num) r=mid;            else if(f((LL)mid,(LL)j)<=num&&f((LL)(mid+1),(LL)j)>num)                break;            else l=mid+1;        }        if(r!=mid)            cnt+=mid;//当前<=num有多少个    }    return cnt<m;}int main(int argc, char const *argv[]){    int t;    scanf("%d",&t);    while(t--){        scanf("%d %lld",&n,&m);        LL l=-inf,r=inf;        while(l<r){            LL mid=(LL)(floor((l+r)/2.0+eps));            if(judge(mid)) l=mid+1;            else r=mid;        }        printf("%lld\n",l );    }    return 0;}
0 0
原创粉丝点击