UVa 10570

链接:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1511

题意:

输入1~n的一个排列(3≤n≤500),每次可以交换两个整数。用最少的交换次数把排列变成1~n的一个环状排列。

分析:

莫名奇妙地AC了。。。方法是枚举起点,然后把数字逐个地安排到正确的位置。但为什么把1作为起点会错呢?

代码:

 1 #include <cstdio>
 2 #include <deque>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 int solve(int n, deque<int> Q){
 7     int res = 0, p[500+5]; //p[i]为数字i在Q中的位置
 8     for(int i = 0; i < n; i++) p[Q[i]] = i;
 9     for(int i = 0; i < n; i++){
10         if(Q[i] == i + 1) continue;
11         p[Q[i]] = p[i+1];
12         swap(Q[i], Q[p[i+1]]);
13         res++;
14     }
15     return res;
16 }
17 
18 int main(){
19     int n;
20     while(scanf("%d", &n) && n){
21         deque<int> Q;
22         for(int v, i = 0; i < n; i++){
23             scanf("%d", &v);
24             Q.push_back(v);
25         }
26         int ans = 1234567890;
27         for(int i = 0; i < n; i++){
28             Q.push_back(Q.front());
29             Q.pop_front();
30             ans = min(ans, solve(n, Q));
31         }
32         reverse(Q.begin(), Q.end());
33         for(int i = 0; i < n; i++){
34             Q.push_back(Q.front());
35             Q.pop_front();
36             ans = min(ans, solve(n, Q));
37         }
38         printf("%d
", ans);
39     }
40     return 0;
41 }
原文地址:https://www.cnblogs.com/hkxy125/p/8531253.html