题意:给一个由1-n的整数组成的数列。对其进行交换两个数的操作。请问最少需要多少次操作,使得数列变成升序的1-n
思路:
举个例子来说,2 5 4 3 1。我们让 i 从1开始判断是否在i是否在该在的位置上。此时i=1不在位置1上,而且位置1上是2。2应该放在位置2上,而位置2上是5。位置5上是1。这就说明1,2,5三个数轮换一下,就能将这三个数换到各自应该在的位置。需要换2次。
顺着这个思路想,可以把1,2,5看成一个环,3,4看成另一个环。那么最后的答案就是 整个数列中不在各自该在位置的数的数量 - 环数。此例子中,就是5-2=3
所以,一个环中,如果有x个数,那么这个环需要x-1次操作。剩下的重点就是找出所有的环了。
int d[10005];
int t[10005];
int main()
{
int tt;
cin>>tt;
while (tt--) {
int n;
cin>>n;
int i;
for (i = 1; i <= n; ++i) {
cin>>d[i];
}
memset(t, 0, sizeof(t));
int ans = n;
for (i = 1; i <= n; ++i) {
if (t[d[i]] == 1) continue;
int start = i;
int x = i;
t[x] = 1;
while (1) {
x = d[x];
t[x] = 1;
if (x == start)
break;
}
--ans;
}
printf("%d\n", ans);
}
return 0;
}