链接:
https://codeforces.com/problemset/problem/1510/K
题意:
给2*n个数,你可以进行以下两种操作:
- Swap p1 and p2, p3 and p4, ..., p2n−1 and p2n.
- Swap p1 and pn+1, p2 and pn+2, ..., pn and p2n
问怎么才能用这两种操作,使这2*n个数字变成递增的序列。输出最小值。
本题数据量很小,所以直接暴力,如果连续做两次同一操作序列不变,所以只有121...或212...两种操作顺序。
代码如下:
#include<iostream>
#include<vector>
#include<cmath>
#include<map>
#include<algorithm>
#include<string>
#include<string.h>
#include<random>
using namespace std;
typedef long long ll;
int n;
int num[2003];
int ori[2003];
bool checkans() {
for (int i = 1; i <= 2 * n; i++) {
if (num[i] != i) {
return false;
}
}
return true;
}
bool check() {
for (int i = 1; i <= 2 * n; i++) {
if (num[i] != ori[i]) {
return 0;
}
}
return 1;
}
void swap1() {
for (int i = 1; i <= 2 * n; i+=2) {
swap(num[i], num[i + 1]);
}
}
void swap2() {
for (int i = 1; i <= n; i++) {
swap(num[i], num[n+i]);
}
}
int main() {
cin >> n;
for (int i = 1; i <= 2*n; i++) {
cin >> num[i];
ori[i] = num[i];
}
ll ans = 2147483647;
ll cnt = 0;
while (!checkans()) {
swap1();
cnt++;
if (check()) {
cnt = 2147483647;
break;
}
if (checkans()) {
break;
}
swap2();
cnt++;
if (check()) {
cnt = 2147483647;
break;
}
}
ans = min(ans, cnt);
cnt = 0;
for (int i = 1; i <= 2 * n; i++) {
num[i] = ori[i];
}
while (!checkans()) {
swap2();
cnt++;
if (check()) {
cnt = 2147483647;
break;
}
if (checkans()) {
break;
}
swap1();
cnt++;
if (check()) {
cnt = 2147483647;
break;
}
}
ans = min(ans, cnt);
if (ans == 2147483647) {
cout << -1;
}
else {
cout << ans;
}
return 0;
}