UVALive - 3695 Distant Galaxy 暴力

题目大意:给出平面上的n个点,找一个矩形,使得边界上包含尽量多的点

解题思路:先找出所有的水平边,然后再找竖直边,用三个数组记录竖直边的状况,left记录该竖直边左边有多少个点在两条水平边上,on记录该竖直边上有多少个点(不包括竖直边和水平边交点上的点),on2记录竖直边上有多少个边(包括水平边和竖直边的交点上的点),这样的话,再边扫描边边统计即可

#include
#include
#include
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;
}


你可能感兴趣的:(ACM-高效算法设计)