CF1157F Maximum Balanced Circle

思路

观察到答案一定是连续的一段下凸函数或者上凸函数
直接模拟找出即可
时间复杂度为\(O(n)\)

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,a[200200],times[200200],minval=0x3f3f3f3f,maxval=0,ansbegin,anslast,ansnum,beginx,last,num,belong;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        minval=min(minval,a[i]);
        maxval=max(maxval,a[i]);
    }
    for(int i=1;i<=n;i++)
        times[a[i]]++;
    for(int i=minval;i<=maxval;i++)
        if(times[i]&&times[i-1])
            ansnum=2,ansbegin=i-1,anslast=i,belong=1;
    for(int i=minval-1;i<=maxval+1;i++){
        if(times[i]>1){
            num+=times[i];
            last=i;
            if(num>ansnum){
                belong=1;
                ansnum=num;
                ansbegin=beginx;
                anslast=last;
            }
        }
        else if(times[i]==1){
            num+=times[i];
            last=i;
            if(num>ansnum){
                belong=1;
                ansnum=num;
                ansbegin=beginx;
                anslast=last;
            }
            num=0;
            beginx=i+1;
        }
        else{
            num=0;
            beginx=i+1;
        }
    }//上凸

    for(int i=maxval+1;i>=minval-1;i--){
        if(times[i]>1){
            num+=times[i];
            beginx=i;
            if(num>ansnum){
                belong=2;
                ansnum=num;
                ansbegin=beginx;
                anslast=last;
            }
        }
        else if(times[i]==1){
            num+=times[i];
            beginx=i;
            if(num>ansnum){
                belong=2;
                ansnum=num;
                ansbegin=beginx;
                anslast=last;
            }
            num=0;
            last=i-1;
        }
        else{
            num=0;
            last=i-1;
        }
    }// 下凸
    if(belong==1&&times[ansbegin-1]==1&&times[ansbegin]>1)
        ansnum++;
    if(belong==2&&times[anslast+1]==1&&times[anslast]>1)
        ansnum++;
    printf("%d\n",ansnum);
    if(belong==1){
        if(times[ansbegin-1]==1&&times[ansbegin]>1)
            printf("%d ",ansbegin-1);
        for(int i=ansbegin;i<=anslast;i++){
            while(times[i]>1){
                printf("%d ",i);
                times[i]--;
            }
        }
        for(int i=anslast;i>=ansbegin;i--){
            if(times[i])
                printf("%d ",i);
        }
    }
    else{
        if(times[anslast+1]==1&&times[anslast]>1)
            printf("%d ",anslast);
        for(int i=anslast;i>=ansbegin;i--){
            while(times[i]>1){
                printf("%d ",i);
                times[i]--;
            }
        }
        for(int i=ansbegin;i<=anslast;i++){
            if(times[i])
                printf("%d ",i);
        }
    }
    return 0;
}
posted @ 2019-05-03 10:02  dreagonm  阅读(217)  评论(0编辑  收藏  举报