给出平面上的n个点,找一个矩形,使得边界上包含的点尽可能地多。

 

先维护前缀和 col[i][j],row[i][j] ,表示i行前j个的和。。

枚举上下边界,右边界,考虑维护左边届

 

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=200;

 struct T{
 	int x,y ;
 }a[N];
 int X[N],Y[N],w[N][N],T,n,m;
 int R[N][N],C[N][N];
 
 void solve(int cas){
 	int i,j;
 	for(i=1;i<=T;i++){
 		scanf("%d%d",&a[i].x,&a[i].y);
 		X[i]=a[i].x,Y[i]=a[i].y;
 	}
 	sort(X+1,X+1+T); sort(Y+1,Y+1+T);
 	n=unique(X+1,X+1+T)-X-1;
 	m=unique(Y+1,Y+1+T)-Y-1;
 	
 	if(n<=2) {
        printf("Case %d: %d\n", cas,T);
        return;
    }
    memset(R,0,sizeof R);memset(C,0,sizeof C);
    memset(w,0,sizeof w);
 	for(i=1;i<=T;i++){
 		int x=lower_bound(X+1,X+1+n,a[i].x)-X;
 		int y=lower_bound(Y+1,Y+1+m,a[i].y)-Y;
 		w[x][y]=1;
 	}
 	
 	for(i=1;i<=n;i++)
 	 for(j=1;j<=m;j++){
 	 	R[i][j] =R[i][j-1]+w[i][j];
 	 	C[i][j] =C[i-1][j]+w[i][j];
 	 }
 	int ans=0;
 	for(i=1;i<n;i++)
 	 	for(j=i+1;j<=n;j++){
 	 		int t=0; 
 	 		for(int k=1;k<=m;k++){
 	 			ans=max(ans,R[i][k]+R[j][k]+
 	 			C[j-1][k]-C[i][k]+t);
 	 			
 	 			t=max(t,-R[i][k-1]+C[j-1][k]+
 	 			-C[i][k]-R[j][k-1]);
 	 		}
 	 	}
 	
 	printf("Case %d: %d\n",cas, ans);
 }
 signed main(){
 	int cas=0;
 	while(scanf("%d",&T)==1&&T) solve(++cas);
 }

 

posted on 2023-04-15 22:25  towboat  阅读(16)  评论(0)    收藏  举报