uvalive3695(降维+扫描)

题意:
给出n个点,让你找一个矩形,是最多的点在矩形边上;
思路:
看了大白的思路:
就是枚举矩形的上下边;
然后每次枚举出上下边界,就从左往右扫描描;
left[i]表示从这条竖线往左一共几个点在上下两边;

on[i]和on2[i]都表示这条竖线上有几个点,on不包括上下边的,而on2包括;


AC:

#include
#include
#include
using namespace std;

const int  N = 105;
int x[N];
int y[N];
int left[N];
int on[N];
int on2[N];
int n;
struct point{
	int x;
	int y;
}p[N];
int cmp(point a, point b) {
	return a.x < b.x;
}
int solve() {
	sort(p, p + n, cmp);
	sort(y, y + n);
	int	m = unique(y, y + n) - y;
		if(m <= 2) 
			return n;
	int ans = 0;
	for(int i = 0; i < n; i++) {
		for(int j = i + 1; j < n; j++) {
			int uy = y[i];
			int dy = y[j];
			if(uy == dy)
				continue;
			int num = 0;
			for(int k = 0; k < n; k++) {
				if(k == 0 || p[k].x != p[k - 1].x) {
					num++;
					on[num] = on2[num] = 0;
					left[num] = left[num - 1] + on2[num - 1] - on[num - 1];
				}
				if(p[k].y > uy && p[k].y < dy)
					on[num]++;
				if(p[k].y >= uy && p[k].y <= dy)
					on2[num]++;
			}
			if(num <= 2)
				return n;
			int m = 0;
			for(int k = 1; k <= num; k++) {
				ans = max(ans, left[k] + on2[k] + m);
				m = max(m, on[k] - left[k]);
			}
		}
	}
	return ans;
}
int main() {
	int cas = 1;
	while(scanf("%d", &n) && 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",cas++ ,solve());
	}
	return 0;
}


你可能感兴趣的:(算法设计)