题目大意:
给你一个p数组包含2n个数字(1~2n):你可以对它进行两个操作:
1.交换P1P2,P3P4........P2n-1P2n;
2.交换P1Pn+1,P2Pn+2...... PnP2n;
如果能通过多次操作写出1234--2n的顺序,则输出最小操作次数,否则输出-1
题解:因为如果出现操作11 22 类的等于没有操作,所以肯定是12操作相交的12121或者21212。
我们可以通过若干次操作后返回到原本数组之间的操作是否有存在顺序数组进行判断-1这种情况。
我们始终用1212的操作方式使得 原数组->顺序数组->原数组 进行。
如果原数组->原数组之间没有顺序数组出现则输出-1;
如果有,则原数组->顺序数组表示了1212的操作方式,顺序数组->原数组则表示2121的操作方式
//#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long int ll;
const int N = 2e3+5;
int n;
int a[N];//原数组
int b[N];//原数组
void swap1()//操作1
{
for (int i = 1; i <= 2 * n; i += 2){
swap(a[i], a[i + 1]);
}
}
void swap2()//操作2
{
for (int i = 1; i <= n; i++){
swap(a[i], a[i + n]);
}
}
bool ok1()//到顺序ok
{
for (int i = 1; i <= 2 * n; i++){
if (a[i]!= i){
return 0;
}
}
return 1;
}
bool ok2()//回到原来数组
{
for (int i = 1; i <= 2 * n; i++){
if (a[i] != b[i]){
return 0;
}
}
return 1;
}
int main()
{
cin >> n;
for (int i = 1; i <= n * 2; i++)//输入
{
cin >> a[i];
b[i] = a[i];
}
int ans = -1;//定义为-1,用于判断-1的情况
if (ok1())
cout << "0";
else
{
for (int i = 1;;i++){
if (i & 1)//变成顺序,以及从顺序变成原数组
swap1();
else swap2();
if (ok1())
ans = i;//记下是第几步操作
if (ok2())
{
if (ans == -1)
cout << -1;
else
cout << min(ans, i - ans) ;
break;
}
}
}
}