文章目录

Question

有 N 个瓶子,编号 1∼N,放在架子上。

比如有 5 个瓶子:

2 1 3 5 4
要求每次拿起 2 个瓶子,交换它们的位置。

经过若干次后,使得瓶子的序号为:

1 2 3 4 5
对于这么简单的情况,显然,至少需要交换 2 次就可以复位。

如果瓶子更多呢?你可以通过编程来解决。

输入格式
第一行包含一个整数 N,表示瓶子数量。

第二行包含 N 个整数,表示瓶子目前的排列状况。

输出格式
输出一个正整数,表示至少交换多少次,才能完成排序。

数据范围
1≤N≤10000,

输入样例1:
5
3 1 2 5 4
输出样例1:
3
输入样例2:
5
5 4 3 2 1
输出样例2:
2

Ideas

每次交换只会产生两种结果,要么是把一个环拆成两个,要么是把两个环合成一个,最后需要n个自环,所以最少需要n-k(k代表一开始有多少环,一开始的环是这样构造的:指向应该在的位置所对应的值。)

Code

n = int(input())
lis = list(map(int,input().strip().split()))
st = [0 for i in range(n)] # 是否经过,没经过标记为0,否则为1

cnt = 0 # 环的个数
for i in range(n):
if not st[i]:
cnt += 1
j = i
while not st[j]:
st[j] = True # 当前位置走过
j = lis[j] - 1 # 指向应该在的位置,这里减去1的原因是1≤N≤10000 数据是从1开始的
print(n-cnt)