蓝桥杯历届试题——合根植物(java版)

package _2021_01_10;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
public class Ex1 {

	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		int m = cin.nextInt();// 行数
		int n = cin.nextInt();// 列数
		int k = cin.nextInt();// k行连根数据
		int union = 0;// 凑成连根的数据
		List<HashSet<Integer>> list = new ArrayList<HashSet<Integer>>();

		while (k > 0) {
			// 读入一行
			boolean con = false;
			int x = cin.nextInt();
			int y = cin.nextInt();
			k--;

			boolean first = true;
			int f_index = -1;// 记录第一次匹配成功的下标
			int s_index = -1;// 若有,记录下第二次匹配成功的下标,用于作集合的删改

			for (HashSet<Integer> s : list) {
				boolean cot_x = s.contains(x);
				boolean cot_y = s.contains(y);
				if (cot_x && cot_y) {
					con = true;
					break;
				} else if (cot_x && !cot_y) {
					con = true;					
					if (first) {
						union++;
						first = false;
						f_index = list.indexOf(s);
						s.add(y);
						list.set(f_index, s);
					} else {// 第二次匹配成功
						union--;
						s_index = list.indexOf(s);
						HashSet<Integer> new_set = list.get(f_index);
						new_set.addAll(s);
						list.set(f_index, new_set);
						break;
					}

				} else if (!cot_x && cot_y) {
					con = true;
					if (first) {
						union++;
						first = false;
						f_index = list.indexOf(s);
						s.add(x);
						list.set(f_index, s);
					} else {// 第二次匹配成功
						union--;
						s_index = list.indexOf(s);
						HashSet<Integer> new_set = list.get(f_index);
						new_set.addAll(s);
						list.set(f_index, new_set);
						break;
					}

				}
			}
			if (s_index != -1)
				list.remove(s_index);// 合并
			if (!con) {
				union = union+2;
				HashSet<Integer> new_data = new HashSet<Integer>();
				new_data.add(x);
				new_data.add(y);
				list.add(new_data);
			}
		}
		System.out.println(list.size() + (m * n - union));
		cin.close();
	}
}



本次设计几乎未进行任何的算法优化,属于暴力求解,效率很低。如果追求更高的效率,可以选择使用递归的方法,或者可以利用图的深度优先遍历的次数来求解,都能以一个较高的效率求得题解。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值