传送门: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<<"**** "; 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 ",cnt); for(int i=1;i<=cnt;i++){ printf("%d %d ",ans[i][1],ans[i][2]); } } return 0; }