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}](https://icpcarchive.ecs.baylor.edu/external/36/p3695.jpg)
Input
There are multiple test cases in the input file. Each test case starts with one integerN ,(1N
100) , the number of star systems on the telescope. N lines follow, each line consists of two integers: theX andY coordinates of theK -th planet system. The absolute value of any coordinate is no more than109 , 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个点,找一个矩阵,使得边界包含尽量多的点。
思路:不能枚举4条边界,O(n^5)的复杂度,要部分枚举,只枚举上下界。
矩阵上的点:T+B+R+L3-(L1+L2)
设:
on[i] = L3
on2[j] = R
left[i] = L1+L2
left[j] = T+B
#include<cstdio> #include<algorithm> using namespace std; const int maxn = 100 + 10; struct Point { int x, y; bool operator < (const Point& rhs) const { return x < rhs.x; } } P[maxn]; int n, m, y[maxn], on[maxn], on2[maxn], left[maxn]; int solve() { sort(P, P + n); sort(y, y + n); m = unique(y, y + n) - y; // 所有不同的y坐标的个数 if (m <= 2) return n; // 最多两种不同的y int ans = 0; for (int a = 0; a < m; a++) for (int b = a + 1; b < m; b++) { int ymin = y[a], ymax = y[b]; // 计算上下边界分别为ymin和ymax时的解 // 计算left, on, on2 int k = 0; for (int i = 0; i < n; i++) { if (i == 0 || P[i].x != P[i - 1].x) // 一条新的竖线 { k++; on[k] = on2[k] = 0; left[k] = (k == 0 ? 0 : left[k - 1] + on2[k - 1] - on[k - 1]); } if (P[i].y > ymin && P[i].y < ymax) on[k]++; if (P[i].y >= ymin && P[i].y <= ymax) on2[k]++; } if (k <= 2) return n; //最多两种不同的x int M = 0; for (int j = 1; j <= k; j++) { ans = max(ans, left[j] + on2[j] + M); M = max(M, on[j] - left[j]);//动态维护on[j] - left[j] } } return ans; } int main() { int kase = 0; 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", ++kase, solve()); } return 0; }