原题链接

考察:图论

思路:

        一道和这极像的题目 212. 计数交换 但是计数交换比本题难多了.这道题关键在于发现将序列变成升序的次数就是环的长度-1.用a[i]数组记录第i个位置是什么数,可以发现i与a[i]之间能连成环.用dfs找环长度即可.

或者可以用贪心法,只要不在应该在的位置上就交换.

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 using namespace std;
 5 const int N = 10010;
 6 int a[N];
 7 bool st[N];
 8 int dfs(int u)
 9 {
10    if(st[u])
11    {
12          return 0;
13    }
14    st[u] = 1;
15    return 1+dfs(a[u]);
16 }
17 int main()
18 {
19     int n,ans = 0;
20     scanf("%d",&n);
21     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
22     for(int i=1;i<=n;i++)
23     {
24         if(!st[i])
25         {
26             int len = dfs(i);
27             ans+=len-1;
28         }
29     }
30     printf("%d\n",ans);
31     return 0;
32 }