• Matrix POJ


    传送门:https://vjudge.net/contest/363330#problem/A

    题意,nxn的矩阵,每列都是递增的,求整个矩阵中从小到大第m个的数是什么

    易错点:  算法中二分找的是一个数x,比它小的数有m个,这样x减一就等等于第m个的数了。

    如果直接二分找一个结果res,比res小的数有m-1个,但这时如果m = 1,就会造成二分结果并不是最小的那个数。

    然后在每一列二分的时候,思路是这样的,找到大于等于k的第一个位置,位置-1就是当前要积累的结果

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <string>
    #include <map>
    #include <stack>
    #include <vector>
    #include <set>
    #include <queue>
    #define maxn 50005
    #define mod 1000000000
    #define INF 0x3f3f3f3f
    using namespace std; 
    typedef long long ll;
    ll n,m,ans;
     
    ll f(ll x,ll y)
    {
        return x*x+100000*x+y*y-100000*y+x*y;
    }
    ll calnum(ll k)
    {
        ll i,j;
        ll le,ri,mid,sum=0;
        for(j=1;j<=n;j++)  // 对每列进行枚举
        {
            le=1;
            ri=n+1;
            while(le<ri)   // 找比k小的数
            {
                mid=(le+ri)>>1;
                if(f(mid,j)>=k) ri=mid;
                else le=mid+1;
            }
            sum+=le-1;
        }
        return sum;
    }
    void solve()
    {
        ll le,mid,ri,t;
        ri=1LL<<50;
        le=-ri;
        while(le<ri)  // 二分找答案
        {
            mid=(le+ri)>>1;
            t=calnum(mid);
            if(t>=m) ri=mid;
            else le=mid+1;
        }
        ans=le-1;
    }
    int main()
    {
        int i,j,t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%lld%lld",&n,&m);
            solve();
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    快速排序和随机化快排学习
    P1330 封锁阳光大学 DFS
    P2577 [ZJOI2005]午餐 状压DP
    M. Subsequence 南昌邀请赛
    P1441 砝码称重 DFS回溯+DP
    P2661 信息传递 二分图的最小环
    P1196 [NOI2002]银河英雄传说 带权并查集
    P2024 [NOI2001]食物链 并查集
    F. Shovels Shop 背包DP
    P1514 引水入城 DFS
  • 原文地址:https://www.cnblogs.com/SunChuangYu/p/12634150.html
Copyright © 2020-2023  润新知