zoukankan      html  css  js  c++  java
  • Wannafly summer camp Day2I(思维)

    #include<bits/stdc++.h>
    using namespace std;
    int a[1000007],b[1000007],c[1000007];
    int find_max(int lll,int rrr,int lenn){
        int maxnn=0;
        int summ=0;
        for(int i=lll;i<=rrr;i++){
            maxnn=max(maxnn,c[i]);
            if(maxnn==lenn+i-lll)//这一段可以经过排序满足题意
                summ++;
        }
        return summ;
    }
    int divide(int l,int r){
        int num=1;
        int len=r-l+1;
        int ll=1;
        for(int i=l;i<=r;i++){
            c[i-l+1]=a[i]-l+1;//对于这一段进行操作,每一段的值都是l到r之间的值,全部减去l-1
        }
        int minn=0;
        for(int i=1;i<=len;i++){
            if(i==1)
                minn=c[1];
            else
                minn=min(minn,c[i]);
            if(minn==len+1-i){//这一段可以和另一半交换
                if(ll==1&&i==len)
                    continue;//不可交换串
                if(ll==1||i==len)
                    num=max(2,num);//至少可以分成两串
                else{
                    int xx=find_max(ll,i,len-i+1);//边上两串交换,中间串尽可能分割
                    num=max(xx+2,num);
                }
                ll=i+1;//下一段的左端点
            }
        }
        return num;
    }
    int main(){
        int n,k;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        scanf("%d%d",&n,&k);
        int maxn=0;
        int sum=0;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            maxn=max(maxn,a[i]);
            if(maxn==i)//如果最大值和i相等,说明从上一个b[i]+1到i之间的串是可以经过排序满足题意的
                b[i]=i,sum++;//如果sum已经达到k了,就无需去交换操作了
        }
        int ans=sum;
        int flag=1;
        if(ans>=k)
            printf("Yes");
        else{
            for(int i=1;i<=n;i++){
                if(b[i]==i){
                    int x=divide(flag,i)-1;//看看每一段中间经过交换操作能多出几段
                    ans=max(ans,sum+x);
                    flag=i+1;//下一段的左端点
                }
            }
            if(ans>=k)
                printf("Yes");
            else
                printf("Poor Simon");
        }
        return 0;
    }
    //通过对一段l到r的串进行构造和思考,可以发现满足题意都是l到r之间值都为l到r之间的
    //一段想要通过交换得到更多段,需要把中间隔成若干尽可能多的段,两端的段交换,中间的分段,可以使段尽可能的多

    保持热爱 不懈努力 不试试看怎么知道会失败呢(划掉) 世上无难事 只要肯放弃(划掉)
  • 相关阅读:
    mysql-sql中变量的使用
    group by 几种不同情况下的聚合运算
    idea中git撤回commit内容
    mysql按照指定的顺序排序(order by case when)
    根据字段的不同值进行升序和降序排序
    索引
    idea 新建git分支并提交
    idea 编辑区浏览器图标
    idea 首字母小写的时候没有相关提示
    Excel—分组然后取每组中对应时间列值最大的或者最小的
  • 原文地址:https://www.cnblogs.com/ldudxy/p/9751329.html
Copyright © 2011-2022 走看看