藍橋杯 歷屆試題 合根植物 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
樣例說明
  其合根情況參考下圖


命名比較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分的,需要多提交幾次。感覺還可以優化。希望大家多提提意見。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章