考察:图论
思路:
一道和这极像的题目 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 }