LA3695

题目大意:
求出一个矩形可以包含的最多的星星的数量。

思路:
用left数组存位于i左边的上下边界的数量,on数组存不包括上下边界的竖线上包含几个星星,用on2数组存包括上下边界的竖线上包含几个星星。边界上的星星数量就是left[j] - left[i] + on2[j]+on[i]。枚举上下边界,用一个循环求on[i] - left[i]的最大值+上left[j]+on2[j] 相当于枚举左右边界 只需要一层循环。

代码:

#include <iostream>
using namespace std;
#include <stdio.h>
#include <cstring>
#include <algorithm>

struct point {
    int x,y;
    bool operator < (const point & a) const {
        return x < a.x;
    }
};
const int maxn = 110;
point p[maxn];
int n;
int y[maxn],on[maxn],on2[maxn],l[maxn];
int solve() {
    sort(y,y+n);
    sort(p,p+n);
    int m = unique(y,y+n) - y;
    if(m <= 2) return n;

    int ans = 0;
    for(int i = 0; i < m; i++) {
        for(int j = i + 1; j < m; j++) {
            int ymin = y[i],ymax = y[j];

            int k = 0;
            for(int a = 0 ; a < n; a++) {
                if(a == 0 || p[a].x != p[a - 1].x) {
                    k++;
                    on[k] = on2[k] = 0;
                    l[k] = k == 0?0:l[k - 1] + on2[k - 1] - on[k - 1];
                }
                if(p[a].y > ymin && p[a].y < ymax) on[k]++;
                if(p[a].y >= ymin && p[a].y <= ymax) on2[k]++;
            }
            if(k <= 2) return n;

            int M = 0;
            for(int b = 1; b<= k; b++) {
                ans = max(ans,l[b]+on2[b]+M);
                M = max(M,on[b] - l[b]);
            }
        }
    }
    return ans;
}
int main() {
    int T = 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",T++,solve());
    }
    return 0;
}

你可能感兴趣的:(LA3695)