Codeforces 1374 F. Cyclic Shifts Sorting —— 暴力,貪心

This way

題意:

給你一個長度爲n的串,你每次可以選擇一個點i,然後將ai,ai+1,ai+2a_i,a_{i+1},a_{i+2}循環向右移位一次。讓你輸出選擇的點的次序使得最終的這個串遞增。你最多可以使用的操作次數不超過n2n^2

題解:

這個的話,我以爲我想錯了,爲什麼會這麼簡單呢。
就從小到大枚舉每個位置,然後找到未排序的最小的點的最前面的位置,然後一次往前移兩格,直到當前位置或者當前位置+1的地方,如果是當前位置+1的地方的話,就再移兩次即可。
然後最後兩個數有可能是逆序的,但是不代表不能將他們正序,就像題目中樣例的最後一個。
所以我們只需要從後往前再做一次像上面那樣的操作即可。
最多的次數的話,應該是這麼算的:假設每次都會交換最多次,也就是n/2+1次,然後(首項+末項)*項數/2*2的話,大概就是n22+2n\frac{n^2}{2}+2n
那麼很明顯在n>=3的情況下,它是不會超的。
時間複雜度O(n)O(n)

#include<bits/stdc++.h>
using namespace std;
const int N=505;
int a[N];
vector<int>ans;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        int n;
        scanf("%d",&n);
        ans.clear();
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        int p=1;
        while(p<=n-2){
            int u=p;
            for(int i=p+1;i<=n;i++)
                if(a[i]<a[u])
                    u=i;
            while(u-2>=p)
                swap(a[u],a[u-2]),swap(a[u],a[u-1]),u-=2,ans.push_back(u);
            if(u==p+1)
                swap(a[u-1],a[u+1]),swap(a[u-1],a[u]),u--,ans.push_back(u),ans.push_back(u);
            p++;
        }
        p=n;
        while(p>=3){
            int u=p;
            for(int i=p-1;i;i--)
                if(a[i]>a[u])
                    u=i;
            while(u+2<=p)
                swap(a[u],a[u+2]),swap(a[u],a[u+1]),u+=2,ans.push_back(u-2),ans.push_back(u-2);
            if(u==p-1)
                swap(a[u+1],a[u-1]),swap(a[u],a[u+1]),u++,ans.push_back(u-2);
            p--;
        }
        int f=0;
        for(int i=1;i<n;i++)
            if(a[i]>a[i+1])
                f=1;
        if(f)
            printf("-1\n");
        else {
            printf("%d\n",ans.size());
            for(int i:ans)
                printf("%d ",i);
            printf("\n");
        }
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章