UVALive 3695 Distant Galaxy (部分枚举,扫描维护)

来源:互联网 发布:在淘宝上开店收费吗 编辑:程序博客网 时间:2024/04/29 05:21

http://acm.hust.edu.cn/vjudge/contest/131137#problem/C

题解:
这道题,还是大白书的。
确实没什么想法,想了很久也不知道该怎么写。
最暴力的就是直接枚举4个边界,然后统计一下。这样是O(n^5)的复杂度。
当然考虑优化:
我们仅仅枚举上下界,然后枚举右边界的时候可以顺便维护ans和M=on[j]-Left[j]。
当然,我是直接两重循环维护ans的,所以也不需要维护M。

#include<bits/stdc++.h>using namespace std;const int maxn=105;pair<int,int> P[maxn];int Left[maxn],on[maxn],on2[maxn],Y[maxn];int n;int Solve() {    int newL=unique(Y,Y+n)-Y;    if(newL<=2)return n;    int ans=0;    for(int i=0; i<newL; ++i) {        for(int j=i+1; j<newL; ++j) {            int yMin=Y[i],yMax=Y[j],num=0;            for(int k=0; k<n; ++k) {                if(k==0 || P[k].first^P[k-1].first) {                    ++num;                    on[num]=on2[num]=0;                    Left[num]=(num==0?0:Left[num-1]+on2[num-1]-on[num-1]);                }                on[num]+=(P[k].second>yMin&&P[k].second<yMax);                on2[num]+=(P[k].second>=yMin&&P[k].second<=yMax);            }            if(num<=2)return n;            for(int k=1;k<=num;++k){                for(int l=k+1;l<=num;++l){                    ans=max(ans,Left[l]-Left[k]+on2[l]+on[k]);                }            }        }    }    return ans;}int main() {    int Tcase=0;    while(~scanf("%d",&n),n) {        for(int i=0; i<n; ++i) {            scanf("%d%d",&P[i].first,&P[i].second);            Y[i]=P[i].second;        }        sort(P,P+n),sort(Y,Y+n);        printf("Case %d: %d\n",++Tcase,Solve());    }    return 0;}
0 0