版权声明:本文为博主原创文章,未经博主允许不得转载,欢迎添加友链。 https://blog.csdn.net/qq_42835910/article/details/89880396
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?
分析:部分枚举,只枚举矩形的上下边界,用其他方法确定左右边界。对于竖线i,用left[i] 表示左边位于边界上的点(不统计位于该竖线上的点,则横向边界上的点 = left[j] - left[i],i<j),on[i]和on2[i]表示上下边界直角的点数(on[i]不统计上下边界与竖线夹角的点,on2[i]统计)。则给定左右边界i,j。 矩形边界点数 = left[j] - left[i] +on[i] + on2[j].当右边界确定使,on[i] - left[i]应该最大。
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 100 + 5;
struct Point{
int x, y;
bool operator < (const Point &rhs){
return x < rhs.x;
}
}p[N];
int lefts[N], on[N], on2[N], y[N];
int solve(int n){
sort(p, p+n);
sort(y, y+n);
int ans = 0, m = unique(y, y+n) - y; // 所有不同y坐标的个数
if( m <= 2) return n; //最多有两种不同的y
for(int a = 0; a < m; a++){
for(int b = a+1; b < m; b++){
int yMin = y[a], yMax = y[b]; //计算上下边界分别为yMin和yMax时的解
int k = 0; //标记不同的x坐标
lefts[0] = 0;
for(int i = 0; i < n; i++){
if(i == 0 || p[i-1].x != p[i].x){ //一个新的竖线
k++;
on[k] = on2[k] = 0;
lefts[k] = lefts[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, lefts[j]+on2[j]+M);
M = max(M, on[j] - lefts[j]);
}
}
}
return ans;
}
int main(int argc, char** argv) {
int kase = 0, n;
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(n));
}
return 0;
}