因为环状序列一定是递增或者递减,数据范围不大,所以直接枚举所有环状序列逐个计算需要的交换次数,取最小即可。
交换的时候贪心策略是总是先把一个数换到应有的位置上。
因为这样n次至少可以让n个数归位,而如果一次想让两个数归位,则至少需要通过传递交换两次,也是相当于一次让一个数归位。
1 #include <stdio.h> 2 #include <iostream> 3 #include <bits/stdc++.h> 4 #include <cstdio> 5 #include <cstring> 6 #include <sstream> 7 #define inf 999999 8 9 using namespace std; 10 11 typedef long long ll; 12 const int maxn = 500+10; 13 int a[maxn]; 14 int t[maxn]; 15 int r[maxn]; 16 int ans[maxn]; 17 int n; 18 19 int solve(int pos){ 20 int num1,num2; 21 num1 = num2 = 0; 22 ans[pos] = 1; 23 for(int i = pos+1 ; i <= n ; i++){ 24 ans[i] = ans[i-1] + 1 > n ? 1 : ans[i-1] + 1; 25 } 26 ans[1] = ans[n] + 1 > n ? 1 : ans[n]+1; 27 for(int i = 2 ; i < pos ; i++){ 28 ans[i] = ans[i-1] + 1 > n ? 1 : ans[i-1] + 1; 29 } 30 memcpy(t,a,sizeof(a)); 31 for(int i = 1 ; i <= n ; i++){ 32 if(t[i] == ans[i])continue; 33 for(int j = i+1 ; j <= n ; j++){ 34 if(t[j] == ans[i]){ 35 num1++; 36 swap(t[i],t[j]); 37 break; 38 } 39 } 40 } 41 ans[pos] = n; 42 for(int i = pos + 1 ; i <= n ; i++){ 43 ans[i] = ans[i-1] - 1 < 1 ? n : ans[i-1] -1; 44 } 45 ans[1] = ans[n]-1 < 1 ? n : ans[n] - 1; 46 for(int i = 2 ; i < pos ; i++){ 47 ans[i] = ans[i-1] -1 < 1 ? n : ans[i-1] - 1; 48 } 49 memcpy(r,a,sizeof(a)); 50 for(int i = 1 ; i <= n ; i++){ 51 if(r[i] == ans[i])continue; 52 for(int j = i + 1 ; j <= n ; j++){ 53 if(r[j] == ans[i]){ 54 swap(r[i],r[j]); 55 num2 ++; 56 break; 57 } 58 } 59 } 60 return min(num1,num2); 61 } 62 int main(int argc, char const *argv[]) 63 { 64 while(cin >> n && n){ 65 for(int i = 1 ; i <= n ; i++){ 66 cin >> a[i]; 67 } 68 int Min = inf; 69 for(int i = 1 ; i <= n ; i ++){ 70 Min = min(Min,solve(i)); 71 } 72 cout << Min << endl; 73 } 74 return 0; 75 }