蓝桥杯 历届试题 合根植物 JAVA

问题描述   w星球的一个种植园,被分成 m * n 个小格子(东西方向m行,南北方向n列)。每个格子里种了一株合根植物。

  这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成为一体。

  如果我们告诉你哪些小格子间出现了连根现象,你能说出这个园中一共有多少株合根植物吗? 输入格式   第一行,两个整数m,n,用空格分开,表示格子的行数、列数(1<m,n<1000)。

  接下来一行,一个整数k,表示下面还有k行数据(0<k<100000)

  接下来k行,第行两个整数a,b,表示编号为a的小格子和编号为b的小格子合根了。

  格子的编号一行一行,从上到下,从左到右编号。

  比如:5 * 4 的小格子,编号:

  1 2 3 4

  5 6 7 8

  9 10 11 12

  13 14 15 16

  17 18 19 20 样例输入 5 4

16

2 3

1 5

5 9

4 8

7 8

9 10

10 11

11 12

10 14

12 16

14 18

17 18

15 19

19 20

9 13

13 17 样例输出 5 样例说明   其合根情况参考下图
《蓝桥杯 历届试题 合根植物 JAVA》

命名比较Low。 百度上没有java的,只好自己写喽


我的 思路: 遍历每个块,假设1号方块,通过输入,给1号方块可达方块添加进该块的list集合,并且把能到达1号方块的方块也添加进1号方块的list集合。 即有向变无向。 然后就递归方块一条路走到黑,然后count++; 最后输出count就行。

上面的例子: 4->8,7->8, 但是遍历会递归4,到8之后不能到7,但是有7->8. 所以如何把7->8转换为8->7也有路是关键。最终解决方法不难,不过对于萌新来说还是累啊哈哈

备注都在代码上了。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Scanner;
public class Main {
	static Scanner scanf=new Scanner(System.in);
	static HashMap<Integer, Zw> hm=new HashMap<Integer,Zw>();		//hashmap键值对不需要遍历
	static int count=0;	//计数
	public static void main(String[] args) {
		int m=scanf.nextInt();	//行
		int n=scanf.nextInt();		//列
		for (int i = 0; i < m*n; i++) {
			Zw zw=new Zw();
			hm.put(i+1, zw);		//给每个方格一个编号
		}
		int k=scanf.nextInt();	//边数
		for (int i = 0; i < k; i++) {
			int start=scanf.nextInt();	//边的起点	
			int end=scanf.nextInt();		//边的终点
			Zw zw=hm.get(start);	//取出一个点
			zw.to.add(end);	//给该点可达点添加进集合
			Zw zw2=hm.get(end);	//重点!敲黑板     
			zw2.to.add(start);//当该点被可达时也添加进,  即有向改无向
		}
		for (int i = 1; i <=m*n; i++) {
			digui(i,true);	//第一个参数是遍历,第二个表示是最外层递归,最后计数要做判断
		}
		System.out.println(count);//答案
	}
	public static void digui(int i,boolean b){
		if(!hm.get(i).life){	//如果该块没有被走过再进入
			hm.get(i).life=true;	//先设为true表示被走过
			ArrayList<Integer> list=hm.get(i).to;	//得到该块可达路径集合(包括被可达路径)
			Iterator<Integer> iterable= list.iterator();	//迭代
			while (iterable.hasNext()) {	//如果有可达路径进入循环
				int temp=iterable.next();	//得到可达点
					digui(temp,false);	//遍历可达路径的可达路径
			}
			if(b){	//如果是最外层循环结束,即一条路走完。
				count++;
			}
		}
	}
}
class Zw{
	public ArrayList<Integer> to=new ArrayList<Integer>();	//可达路径集合
	boolean life=false;	//该点是否被遍历过
}

这个代码,在蓝桥杯评测不是100%得100分的,需要多提交几次。感觉还可以优化。希望大家多提提意见。

    原文作者: 汉诺塔问题
    原文地址: https://blog.csdn.net/qq_35984195/article/details/79202555
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞