問題描述
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
接下來一行,一個整數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
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分的,需要多提交幾次。感覺還可以優化。希望大家多提提意見。