B - Dreamoon Likes Permutations思维

传送门:https://codeforces.ml/contest/1330/problem/B

题意

  给出一个长为n的序列,要求把它分成两部分,两部分均为一个连续的自然数列,问能有几种分法,给出分出来的两部分序列长度。

思路

  设这个序列最大值为ma,那么必定有一部分的长度为ma,因为是自然数列数应该从1到ma不重样,所以长度为ma,那么另一部分的长度就是n-ma了,所以我们尝试把序列分成ma和n-ma两个部分,如果ma不是n的一半的话尝试分成n-ma和ma两个部分,设一部分的长度为len,我们只要用个标记数组看1到len是否全部出现即可。做题的时候没有考虑好清楚序列的断点,导致写了一百多行左边来一次右边来一次,之后一定要想清楚再敲,切记切记。

ac代码

#include<iostream>
using namespace std;
const int maxn=2e5+5;
int a[maxn],vis[maxn],ans[5][5];
int t,cnt,n,ma;

bool check(int l1,int l2){
    for(int i=1;i<=n;i++) vis[i]=0;
    for(int i=1;i<=l1;i++) vis[a[i]]=1;
    for(int i=1;i<=l1;i++){
        if(vis[i]==0) return 0;
    }
    for(int i=1;i<=n;i++) vis[i]=0;
    for(int i=l1+1;i<=n;i++) vis[a[i]]=1;
    for(int i=1;i<=l2;i++){
        if(vis[i]==0){
            //cout<<"****\n";
            return 0;
        }
    }
    return 1;
}

int main()
{
    cin>>t;
    while(t--){
        cin>>n;
        ma=-1;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            ma=max(ma,a[i]);
        }
        cnt=0;
        if(check(ma,n-ma)){
            cnt++;
            ans[cnt][1]=ma;
            ans[cnt][2]=n-ma;
        }
        if(ma*2!=n&&check(n-ma,ma)){
            cnt++;
            ans[cnt][1]=n-ma;
            ans[cnt][2]=ma;
        }    
        printf("%d\n",cnt);
        for(int i=1;i<=cnt;i++){
            printf("%d %d\n",ans[i][1],ans[i][2]);
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/qq2210446939/p/12643534.html