zoukankan      html  css  js  c++  java
  • 【bzoj5085】最大(二分+乱搞)

      题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=5085

      这道题我们可以先二分答案,然后转化为判定是否有四角权值>=mid的矩形。

      我们可以发现,若4个点可以构成矩形,那么这四个点一定两两在同一行,同一列。

      于是我们可以把每一行的合法点处理出来,在里面枚举点对。若有一个点对出现了两次,那么就说明在上面的某一行的相同列有两个合法点,即能构成矩形。

      因为找到两对相同的合法点对就可以反回结果,而合法点对的规模是$ O(m^2) $的,因此总时间复杂度$ O(m^2log(n)) $。

    ·  (然而我因为读入写错tle了好几发。。。qwq)

      代码:

    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<ctime>
    #include<iostream> 
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<map>
    #define ll long long
    #define ull unsigned long long
    #define max(a,b) (a>b?a:b)
    #define min(a,b) (a<b?a:b)
    #define lowbit(x) (x& -x)
    #define mod 10000007
    #define inf 0x3f3f3f3f
    #define eps 1e-10
    #define maxn 1010
    inline char nc(){
        static char buf[100000],*p1=buf,*p2=buf;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    inline ll read(){ll tmp=0; char c=nc(),f=1; for(;c<'0'||'9'<c;c=nc())if(c=='-')f=-1; for(;'0'<=c&&c<='9';c=nc())tmp=(tmp<<3)+(tmp<<1)+c-'0'; return tmp*f;}
    inline ll power(ll a,ll b){ll ans=1; for(;b;b>>=1){if(b&1)ans=ans*a%mod; a=a*a%mod;} return ans;}
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline void swap(int &a,int &b){int tmp=a; a=b; b=tmp;}
    using namespace std;
    int a[maxn][maxn],vis[maxn][maxn];
    int x[maxn];
    int n,m;
    int check(int mid)
    {
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++){
            int tot=0;
            for(int j=1;j<=m;j++)
                if(a[i][j]>=mid)x[++tot]=j;
            for(int j=1;j<tot;j++)
                for(int k=j+1;k<=tot;k++)
                    if(vis[x[j]][x[k]])return 1;
                    else vis[x[j]][x[k]]=1;
        }
        return 0;
    }
    int main()
    {
        n=read(); m=read();
        int l=inf,r=-inf;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                a[i][j]=read(),l=min(l,a[i][j]),r=max(r,a[i][j]);
        while(l<r){
            int mid=(l+r+1)>>1;
            if(check(mid))l=mid;
            else r=mid-1;
        }
        printf("%d
    ",l);
    }
    bzoj5085

      Tips:听说找到权值最大的前4n个点直接爆枚就行了?然而我不会证。

  • 相关阅读:
    7. Bagging & Random Forest
    VS 多工程代码编写
    C++(vs)多线程调试 (转)
    halcon发布
    windows 批处理文件调用exe
    Halcon编程-基于形状特征的模板匹配
    缺陷检测 深度学习
    PID控制
    去掉图片中的红色标记的方法?
    图像处理之图像拼接四
  • 原文地址:https://www.cnblogs.com/quzhizhou/p/9598022.html
Copyright © 2011-2022 走看看