CF 333D Characteristics of Rectangles

因为是最小值的最大值,首先我们想到用二分来查找答案。
剩下的就是实现判断mid是否可行的方法。
我们用vis[i][j]表示是否某行的i,j是大于等于mid的。
当下次出现i,j便说明2行组成一个矩形是可行的。

	for(int i=1;i<=n;i++){
	 cnt=0;
		for(int j=1;j<=m;j++)
		 if(a[i][j]>=mid){cnt++;p[cnt]=j;}
		int ax=0;
		for(int j=1;j<=cnt;j++)
		  for(int k=1;k<j;k++){
		  if(vis[p[k]][p[j]])return 1;
		  vis[p[k]][p[j]]=1;
		  }

复杂度;i,j最多的组合是n*(n-1)/2。判断的复杂度近似可以看成n*m.
总复杂度为o(nm*log a[][])

#include<bits/stdc++.h>
using namespace std;
const int N=1030;
int mid,l,r,m,n,p[N],jj[N],a[N][N],vis[N][N],miner=1e9,maxer;
bool az(){
    memset(vis,0,sizeof(vis));
    int cnt=0;
    for(int i=1;i<=n;i++){
     cnt=0;
        for(int j=1;j<=m;j++)
         if(a[i][j]>=mid){cnt++;p[cnt]=j;}
        int ax=0;
        for(int j=1;j<=cnt;j++)
          for(int k=1;k<j;k++){
          if(vis[p[k]][p[j]])return 1;
          vis[p[k]][p[j]]=1;
          }
    }
    return 0;
}
int main()
{    //freopen("p.in","r",stdin);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++){
     scanf("%d",&a[i][j]);
     miner=min(miner,a[i][j]);
     maxer=max(maxer,a[i][j]);
     }
    l=miner;r=maxer;
    while(l<r){
    mid=l+(r-l+1)/2;
    if(az())l=mid;
        else r=mid-1;
    }
    cout<<r;
    return 0;
}
View Code

 实现查找满足条件的最大值

    while(l<r){
    mid=l+(r-l+1)/2;
    if(az())l=mid;
        else r=mid-1;
    }
View Code

 

posted @ 2018-08-29 15:37  周栎  阅读(298)  评论(0编辑  收藏  举报