牛客寒假训练营第二场F牛牛与交换排序deque

88 阅读1分钟

题目链接

题目链接

题解

这题不难发现可以先确认K,难点在于check取K是否可行。

可以用双端队列实现,确认出k之后,让双端队列中始终保持k个数,从一端pop的同时,另一端push。比较灵活,细节看注释。

代码

/*
 * @Author: hesorchen
 * @Date: 2020-11-26 09:12:46
 * @LastEditTime: 2021-02-03 22:12:26
 * @Description: 栽种绝处的花
 */
#include <bits/stdc++.h>
using namespace std;

int a[100010];

deque<int> q;
int main()
{
    q.clear();
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    int flag = 1, lenth;
    for (int i = 1; flag && i <= n; i++) //先确定k的值
    {
        if (a[i] != i)
        {
            for (int j = i + 1; flag && j <= n; j++)
            {
                if (i == a[j])
                {
                    lenth = j - i + 1;
                    flag = 0;
                }
            }
        }
    }
    if (flag) //如果本来就有序,直接输出yes
        return puts("yes\n1"), 0;
        
    int pos = 1, beg = 1;
    while (q.size() < lenth) //先压入lenth个
        q.push_back(a[pos++]);
    while (pos <= n)
    {
        int ff = 0;
        if (q.front() == beg) //如果前端满足,从前端开始弹出
        {
            while (pos <= n && q.front() == beg)
            {
                ff = 1;
                beg++;
                q.pop_front();
                q.push_back(a[pos++]);
            }
        }
        else //如果后端满足,从前端开始弹出
        {
            while (pos <= n && q.back() == beg)
            {
                ff = 1;
                beg++;
                q.pop_back();
                q.push_front(a[pos++]);
            }
        }
        if (!ff) //如果两端都不满足,输出no
            return puts("no"), 0;
    }

    //判断队列中最后的lenth个数是不是有序
    int now = n - lenth + 1; //剩下的数中,最小的应该是now
    if (q.front() == now)    //只能选择一端开始弹出
    {
        while (q.size() && q.front() == now)
        {
            now++;
            q.pop_front();
        }
    }
    else
    {
        while (q.size() && q.back() == now)
        {
            now++;
            q.pop_back();
        }
    }

    if (q.size() == 0) //如果最后的length数仍然有序,那么输出yes
    {
        puts("yes");
        cout << lenth << endl;
    }
    else
        puts("no");

    return 0;
}