给出平面上的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);
}
浙公网安备 33010602011771号