【牛牛与交换排序】用deque模拟区间反转

牛牛与交换排序
题意是给你一个1-n的排列,问能否存在一个k,使得每次翻转一个长度为k的区间,且每次翻转的区间要比上一次更靠右,问能否找到这样一个k。
手写几组样例便会很清晰地发现,最小的k一定是第一个数字与位置不一样的那个数与自己位置的距离的差值。我们可以令k=abs(pos[i]-i)+1;
接下来就是模拟区间翻转的过程了,我们可以利用stl里面的deque或者写一个平衡树,达到O(n)的复杂度来实现这一过程
这里的deque模拟更多是一种思维的发散,写过类似的题就会写,没写过的话是真的很难想到。具体实现的话,便是在长度为k的队列里,找到翻转后变成位置与数字统一的那个数字,然后把它弹出,插入下一个数,如此反复,用flag来表示弹出的是队首还是队尾
具体实现可以看代码

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
#define rep(i, a, b) for(int i=a;i<=b;i++)
#define per(i, a, b) for(int i=a;i>=b;i--)
using namespace std;
const int maxn=1e5+5;
const ll mod=1e9+7;
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}

int a[maxn],pos[maxn];

int main()
{
    int n=read(),cur=0,k=1;
    rep(i,1,n) a[i]=read(),pos[a[i]]=i;
    rep(i,1,n)
        if(a[i]!=i)
        {
            cur=i;
            k=abs(pos[i]-i)+1;
            break;
        }
    deque<int>q;
    rep(i,cur,cur+k-1)  q.push_back(a[i]);
    int flag=0;// 0代表插入队首,队尾出队; 1代表队首出队,后面的数插入队尾
    for(int i=cur;i+k-1<=n;i++)
    {
        if(q.front()!=i&&q.back()!=i) { puts("no"); return 0;}  //翻转了也无法按顺序升序
        if(!flag&&q.front()!=i) flag^=1;
        if(flag&&q.back()!=i)   flag^=1;

        if(flag){   //插入队首
            q.pop_back();
            if(i+k<=n) q.push_front(a[i+k]);
        }
        else{       //插入队尾
            q.pop_front();
            if(i+k<=n) q.push_back(a[i+k]);
        }
    }
    rep(i,n-k+2,n)//剩下来的留在队列里的数字一一检验是否已经升序
    {
        int now;
        if(!flag) {
            now = q.front();
            q.pop_front();
        }
        else {
            now = q.back();
            q.pop_back();
        }
        if(now != i) { puts("no"); return 0;}
    }
    puts("yes");
    printf("%d\n",k);
}
全部评论

相关推荐

09-16 16:25
门头沟学院 Java
投递长江存储等公司9个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务