交换瓶子
来源: 第七届蓝桥杯省赛C++B组
算法标签 图论 环 置换群 贪心
题目描述
有 N 个瓶子,编号 1∼N,放在架子上。
比如有 5 个瓶子:
2 1 3 5 4
要求每次拿起 2 个瓶子,交换它们的位置。
经过若干次后,使得瓶子的序号为:
1 2 3 4 5
对于这么简单的情况,显然,至少需要交换 2 次就可以复位。
如果瓶子更多呢?你可以通过编程来解决。
输入格式
第一行包含一个整数 N,表示瓶子数量。
第二行包含 N 个整数,表示瓶子目前的排列状况。
输出格式
输出一个正整数,表示至少交换多少次,才能完成排序。
数据范围
输入样例1:
输出样例1:
输入样例2:
输出样例2:
思路
由样例1
3 1 2 5 4
转为
1 2 3 4 5
对于瓶子顺序而言 则会有
3 对应正确顺序的3的位子 即当前的 2
2 对应正确顺序的2的位子 即当前的 1
1 对应正确顺序的2的位子 即当前的 3
这连接则形成一个闭环
总共有两个闭环
环内两个点的变动可以使得环分裂为2
环外的两个点的变动可以使得两个环合并为1
环最简的情况下是 自指,即存在n个环
这种情况同时也是 该题转换为正确顺序之后的情况
则可以遍历出当前所有环的数量 k
从k变更到n 需要n-k步骤
答案即为 n-k
在实际的操作过程当中,遍历环可以从1(i)出发每次指向i=a[i]
即指向指定的目标
时间复杂度
实际从n^2优化到了n
C++ 代码