题目大意:给出平面上的n个点,找一个矩形,使得边界上包含尽量多的点
解题思路:先找出所有的水平边,然后再找竖直边,用三个数组记录竖直边的状况,left记录该竖直边左边有多少个点在两条水平边上,on记录该竖直边上有多少个点(不包括竖直边和水平边交点上的点),on2记录竖直边上有多少个边(包括水平边和竖直边的交点上的点),这样的话,再边扫描边边统计即可
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 110
struct Point{
int x, y;
bool operator < (const Point t) const{
return x < t.x;
}
}p[maxn];
int y[maxn], left[maxn], on[maxn], on2[maxn], N;
int solve() {
sort(p,p+N);
sort(y,y+N);
int num = unique(y,y+N) - y;
if(num <= 2)
return N;
int ans = 0;
for(int i = 0; i < num; i++)
for(int j = i + 1; j < num; j++) {
int ymin = y[i], ymax = y[j];
int cnt = 0;
for(int k = 0; k < N; k++) {
if(k == 0 || p[k].x != p[k-1].x) {
cnt++;
on[cnt] = on2[cnt] = 0;
left[cnt] = left[cnt-1] + on2[cnt-1] - on[cnt-1];
}
if(p[k].y > ymin && p[k].y < ymax)
on[cnt]++;
if(p[k].y >= ymin && p[k].y <= ymax)
on2[cnt]++;
}
if(cnt <= 2)
return N;
int tmp = 0;
for(int k = 1; k <= cnt; k++) {
ans = max(ans,left[k] + on2[k] + tmp);
tmp = max(tmp, on[k] - left[k]);
}
}
return ans;
}
int main() {
int mark = 1;
while(scanf("%d", &N) == 1 && N) {
for(int i = 0; i < N; i++) {
scanf("%d%d",&p[i].x, &p[i].y);
y[i] = p[i].y;
}
printf("Case %d: %d\n",mark++, solve());
}
return 0;
}