CodeForces - 1330B Dreamoon Likes Permutations(思維:最大數=全排列長度)

題目鏈接https://vjudge.net/contest/366677#problem/B
在這裏插入圖片描述
Input

6
5
1 4 3 2 1
6
2 4 1 3 2 1
4
2 1 1 3
4
1 3 3 1
12
2 1 3 4 5 6 7 8 9 1 10 2
3
1 1 1

Output

2
1 4
4 1
1
4 2
0
0
1
2 10
0

翻譯

輸入n個數,求是否能把這個長度爲n的數組分成兩個全排列。
記錄有多少次方法,和每次分成的兩個全排列的長度。
例如:
5
1 4 3 2 1
有2種辦法 {1}+{4,3,2,1}and {1,4,3,2}+{1}

分析
全排列:如果m 個整數的序列包含了1~m的整數,且1到m正好出現一次。m這個數叫做全排列的長度。

ma爲數組中的最大值
如果把數組a分成兩個全排列p1和p2,那麼ma一定是max(len1,len2)。(最大的數值爲全排列的長度

這裏有兩種情況:

  1. len1=ma,len2=n−ma
  2. len1=n−ma,len2=ma

代碼

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2*1e5+10;
int n,a[N];
int mx;
int index[2][2],cnt;
void init()
{
    mx=0;
    cnt=0;
    memset(index,0,sizeof(index));
}
bool solve(int a[],int n)
{
    bool book[N];
    for(int i=1; i<=n; i++)
        book[i]=false;
    for(int i=0; i<n; i++)
        book[a[i]]=true;
    for(int i=1; i<=n; i++)
    {
        if(!book[i])
            return 0;
    }
    return 1;
}
bool judge(int len1,int n)
{
    return solve(a,len1)&&solve(a+len1,n-len1);/*a  a+len1分別爲數組的起始位置,從這個位置開始遍歷*/
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        init();
        scanf("%d",&n);
        for(int i=0; i<n; i++)
        {
            scanf("%d",&a[i]);
            mx=max(mx,a[i]);
        }
        if(judge(n-mx,n))
        {
            index[cnt][0]=n-mx;
            index[cnt++][1]=mx;
        }
        if(mx*2!=n&&judge(mx,n))/*mx*2和n比較,排除兩個全排列的長度相等的情況*/
        {
            index[cnt][0]=mx;
            index[cnt++][1]=n-mx;
        }
        printf("%d\n",cnt);
        for(int i=0; i<cnt; i++)
            printf("%d %d\n",index[i][0],index[i][1]);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章