#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> using namespace std; const int N = 1e6+10; int a[N],vis[N]; //vis数组记录每个数是否找过他应该在的位置 int main() { int t; scanf("%d",&t); while(t--){ memset(vis,0,sizeof(vis)); int ans = 0; int n,i; scanf("%d",&n); for(i = 1; i <= n; i++){ scanf("%d",&a[i]); } for(i = 1; i <= n; i++){ int temp = a[i],x = 0; while(!vis[temp]){ //temp 还没找过其应在的位置 vis[temp] = 1; //标记temo已经找过 temp = a[temp]; //用temp应在的位置上的数覆盖temp,如果其在应在的位置那么继续while循环直接跳出然后不用做交换 x++; } if(x > 0){ ans += x-1; //遍历每一组情况下应该对x减一才能得到正确的交换次数 } } printf("%d\n",ans); } return 0; }
原文:https://www.cnblogs.com/clb123/p/10731929.html