VK Cup 2021 - C. Bottom-Tier Reversals(思维,构造)

C. Bottom-Tier Reversals

思路:

首先想一下什么情况下会无解,因为一共有奇数个数字,而且可交换的前缀串长度也是奇数,所以无论如何变换,起初的数字所在位置的奇偶性一定都不会变,然后讨论如何构造,我们只需要以下5步便可以确定最后2个数字,依次搞定所有数字即可
在这里插入图片描述
代码:

#include <bits/stdc++.h>

#define all(x) (x).begin(), (x).end()
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define make_unique(x) sort((x).begin(), (x).end()); (x).erase(unique((x).begin(), (x).end()), (x).end())
#define OP freopen("D:\\Users\\HP ZBook15\\CLionProjects\\untitled\\demo\\in.TXT","r",stdin);
#define CL freopen("D:\\Users\\HP ZBook15\\CLionProjects\\untitled\\demo\\out.TXT","w",stdout);

using namespace std;

inline int nxt() {
    int x;
    cin >> x;
    return x;
}

void solve() {
    int n = nxt();
    vector<int> a(n);
    for (int i = 0; i < n; ++i) {
        a[i] = nxt() - 1;
    }
    for (int i = 0; i < n; ++i) {
        if (a[i] % 2 != i % 2) {
            cout << "-1\n";
            return;
        }
    }

    vector<int> ans;
    
	//自定义一个变换turn
    auto turn = [&](int l) {
        if (l == 1) {
            return;
        }
        //这五步变换的下标恰都是奇数,可以检查一下
        assert(l % 2);
        ans.push_back(l);
        reverse(a.begin(), a.begin() + l);
    };

    while (n > 1) {
        turn(find(all(a), n - 1) - a.begin() + 1);
        turn(find(all(a), n - 2) - a.begin());
        turn(find(all(a), n - 2) - a.begin() + 2);
        turn(3);
        turn(n);
        n -= 2;
    }
	
	//检查是否排好序了
    assert(is_sorted(all(a)));

    cout << ans.size() << "\n";
    for (int x : ans) {
        cout << x << " ";
    }
    cout << "\n";
}

int main() {
    closeSync
//    OP
//    CL
    int t = nxt();
    while (t--) {
        solve();
    }

    return 0;
}

解释一下assert 语句:

这是用来提高代码可测试性的,可以对某种假设条件进行检查,在 C 语言中,断言被定义为宏的形式(assert(expression)),而不是函数,如果表达式 expression 的值为假(即为 0),那么它将首先向标准错误流 stderr 打印一条出错信息,然后再通过调用 abort 函数终止程序运行;否则,assert 无任何作用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值