uva 1382 Distant Galaxy (枚举)

                          uva 1382 Distant Galaxy


You are observing a distant galaxy using a telescope above the Astronomy Tower, and you think that a rectangle drawn in that galaxy whose edges are parallel to coordinate axes and contain maximum star systems on its edges has a great deal to do with the mysteries of universe. However you do not have the laptop with you, thus you have written the coordinates of all star systems down on a piece of paper and decide to work out the result later. Can you finish this task?

\epsfbox{p3694.eps}

Input

There are multiple test cases in the input file. Each test case starts with one integer N , (1$ \le$N$ \le$100) , the number of star systems on the telescope. N lines follow, each line consists of two integers: the X and Y coordinates of the K -th planet system. The absolute value of any coordinate is no more than 109 , and you can assume that the planets are arbitrarily distributed in the universe.

N = 0 indicates the end of input file and should not be processed by your program.

Output

For each test case, output the maximum value you have found on a single line in the format as indicated in the sample output.

Sample Input

10 
2 3 
9 2 
7 4 
3 4 
5 7 
1 5 
10 4 
10 6 
11 4 
4 6 
0

Sample Output

Case 1: 7



题目大意:给出n个点,问说一个平行与x轴和y轴的矩形,最多能有多少个点落在边上。

解题思路: 先枚举上下边界,然后从左到右扫,扫描一遍所有的点,计算L, on, on2数组,枚举右边界,维护on[i] - L[i]的最大值。


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int n, y[1005], on[1005], on2[1005], L[1005];  
struct point {
	int x, y;
};  
int cmp(point a, point b) {
	return a.x < b.x;
}
point p[1005];
int getAns(){  
	int ans = 0;  
	sort(p, p + n, cmp);  
	sort(y, y + n);  
	int m = unique(y, y + n) - y;  //统计具有不同y坐标的点的个数
	if(m <= 2) return n;  
	for(int a = 0; a < m; a++)          
		for(int b = a + 1; b < m; b++){  
			int miny = y[a], maxy = y[b], k = 0;  //枚举上下边
			memset(on, 0, sizeof(on));  
			memset(on2, 0, sizeof(on2));  
			memset(L, 0, sizeof(L));  
			for(int i = 0; i < n; i++){         
				if(!i || p[i].x != p[i-1].x){  
					k++;  
					if(k > 1) L[k] = L[k - 1] + on2[k - 1] - on[k - 1]; //on2记录边界,on没记录边界,on2-on就是边界上的点的个数, 加上上一条竖线左侧,就是当前竖线左侧点的个数 
				}  
				if(p[i].y < maxy && p[i].y > miny) on[k]++;  
				if(p[i].y <= maxy && p[i].y >= miny) on2[k]++;  
			}  
			if(k <= 2) return n;  
			int Max = 0;  
			for(int i = 1; i <= k; i++){   
				ans = max(ans, L[i] + on2[i] + Max);  //维护Max
				Max = max(Max, on[i] - L[i]);  
			}  
		}  
	return ans;  
}  
int main(){  
	int Case = 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", Case++, getAns());  
	}  
	return 0;  
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值