Codeforces Round #740 Div. 2 E

// Problem: Bottom-Tier Reversals
// Contest: codeforces #740
// URL: https://codeforces.com/contest/1561/problem/E
// Memory Limit:  512MB
// Time Limit:  2000ms
// author:tczz
/* solution:很明显偶数位置的数不能通过翻转成为奇数位的数,奇数位同
理,所以如果奇数在偶数位置或者偶数在奇数位置,那么就是impossible.
下面是构造的方法,从最后一个位置i开始每次构造两位,分为5步:
1.把值为i的数放到最前
2.把值为i的数放到i-1前
3.选择值为i的下一个奇数位置翻转,使得i-1到i前
4.把i放到最前,这时第一位是i第二位是i-1
5.把位置i翻转
恰好两位最多需要5次操作,也就是5n/2
*/

#include <bits/stdc++.h>
using namespace std;

#define ll long long

const int maxn = 3e3 + 10;
int n;
int num[maxn];
vector<int> ans;
void Swap(int cnt)
{
    ans.push_back(cnt);
    for (int i = 1; i <= cnt / 2; i++)
    {
        swap(num[i], num[cnt - i + 1]);
    }
}
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        ans.clear();
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> num[i];
        bool ok = 1;
        for (int i = n; i >= 1; i --)
        {
           if(i%2!=num[i]%2){
               ok=0;
               break;
           }
        }
        if (!ok)
        {
            cout << -1 << endl;
        }
        else
        {
            for(int i=n;i>1;i-=2){
                int pos;
                for(int j=1;i<=i;j++){
                    if(num[j]==i) {
                        pos=j;
                        break;
                    }
                }
                Swap(pos);
                for(int j=1;i<=i;j++){
                    if(num[j]==i-1){
                        Swap(j-1);
                        Swap(j+1);
                        break;
                    }
                }
                for(int j=1;i<=i;j++){
                    if(num[j]==i) {
                        pos=j;
                        break;
                    }
                }
                Swap(pos);
                Swap(i);
            }
            cout << ans.size() << endl;
            for (int ss = 0; ss < ans.size();ss++)
            {
                if (ss != 0)
                    cout << ' ';
                cout << ans[ss];
            }
            cout << endl;
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值