1224. 交换瓶子 Java题解 (置换环,图论)【第七届蓝桥杯省赛C++B组,JAVA A组】

35 篇文章 2 订阅
32 篇文章 1 订阅

输入样例1:

5
3 1 2 5 4

输出样例1:

3

输入样例2:

5
5 4 3 2 1

输出样例2:

2

解题思路:

将瓶子存入数组b中,b[i] = j:表示第i个位置放的j号瓶子。将瓶子想象为图中的每个点,连边方式为:瓶子连向该瓶子本来应该在的位置上的瓶子。即开始时,瓶子应该是形成若干个环,排好序时,环的个数就是瓶子的个数(都是自环)。

当交换同一环内的两个瓶子时,环的个数会加一;当交换不同环上的瓶子时,环的数量会减一。

求最少交换的次数就等价于当前环需要交换多少次可以都形成自环。

Java代码: 

import java.io.*;

public class Main {
	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int n = Integer.parseInt(br.readLine());
		String[] split = br.readLine().split(" ");
		int []battle = new int[n + 1];  //b[i] = j:表示第i个位置放的j号瓶子
		boolean []tag = new boolean[n + 1];  //标记是否访问过
		for(int i = 1; i <= n; i++)
			battle[i] = Integer.parseInt(split[i - 1]);
		
		int ans = 0;  //环的个数
		for(int i = 1; i <= n; i++) {
			if(!tag[i]) {
				ans++;
				for(int j = i; !tag[j]; j = battle[j])  //遍历完整个环
					tag[j] = true;
			}
		}
		System.out.println(n - ans);  //自环数减现有环数
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值