题意:有一个1~n的排列,你每次可以都可以交换两个整数,用最少的次数交换次数把这个序列变成一个1~n的环状排列。
思路:这个就是直接三重循环暴力就好了,如果当前的这个位置不是的话就找到应该放倒当前的位置的数字,然后进行交换。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#define MAXN 1010
#define MAXE 10010
#define INF 100000000
#define MOD 1000000007
#define LL long long
#define pi acos(-1.0)
using namespace std;
int arr[MAXN];
int brr[MAXN];
int main() {
std::ios::sync_with_stdio(false);
int n;
while (cin >> n && n) {
for (int i = 1; i <= n; ++i) {
cin >> arr[i];
}
for (int i = n + 1; i <= 2 * n; ++i) {
arr[i] = arr[i - n];
}
int ans = INF;
for (int k = 1; k <= n; ++k) {
int sum = 0;
memcpy(brr, arr, sizeof(arr));
for (int i = k; i < n + k; ++i) {
if (brr[i] == i - k + 1) {
continue;
}
for (int j = i + 1; j < n + k; ++j) {
if (brr[j] == i - k + 1) {
swap(brr[i], brr[j]);
sum++;
break;
}
}
if (sum > ans) {
break;
}
}
ans = min(sum, ans);
}
reverse(arr + 1, arr + 2 * n + 1);
for (int k = 1; k <= n; ++k) {
int sum = 0;
memcpy(brr, arr, sizeof(arr));
for (int i = k; i < n + k; ++i) {
if (brr[i] == i - k + 1) {
continue;
}
for (int j = i + 1; j < n + k; ++j) {
if (brr[j] == i - k + 1) {
swap(brr[i], brr[j]);
sum++;
break;
}
}
if (sum > ans) {
break;
}
}
ans = min(sum, ans);
}
cout << ans << endl;
}
return 0;
}
/*
4
1 2 3 4
4
4 3 2 1
4
2 3 1 4
0
*/