藍橋杯——種植園問題(prev54)

11.1 題目:
問題描述
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 樣例說明 其合根情況參考下圖
在這裏插入圖片描述

程序一:(並查集)

我的理解:要想尋找一株合根植物,那麼其實就是找連通圖,判斷兩個點是否在連通圖中,因此我們可以建立無向圖,但是用圖的數據結構最大是問題是,算法時效過低,因此我們將這個題目轉化爲對並查集的操作問題。
構建一個連通圖,mat[i]的值是下一個結點的索引位置。當mat[i] = 時代表此時是根節點。

package Mycup;
import java.util.Scanner;

public class test {
	static int[] mat = new int[1000001];
	public static int find(int x){   //找到當前結點所在的連通圖的根節點。返回其索引值。
		while(x != test.mat[x]){
			x = test.mat[x];
		}
		return x;
	}
	public static void liangen(int x,int y){  //如果x在連通圖中,y不在,那麼根節點被賦值爲y,y變爲根節點,如果y在連通圖中,x不在,那麼y還是根節點,但是x加入了該連通圖中。
		mat[find(x)] = find(y);
	}
	public static void main(String[] args){
		int count =0;
		Scanner in = new Scanner(System.in);
		int row = in.nextInt();
		int clo = in.nextInt();

		int k = in.nextInt();
		for (int i =0;i<=row*clo;i++){
			mat[i] = i;
			
		}
		for (int i =0;i<k;i++){
			int x1 = in.nextInt();
			int x2 = in.nextInt(); //獲取連根座標
			test.liangen(x1,x2);
		}
		for(int i =1;i<=row*clo;i++){
			if(find(i) == i)
				count += 1;
		}
		System.out.print(count);
	}
	}

程序二

解法是:如果兩個結點在一個連通圖中,那麼兩個結點的值就是一樣,且其值代表連通圖的序號,因此最後只需將連通圖的序號加上單根植物的棵樹即結果。

package Mycup;
import java.util.Scanner;

public class test {
	static int[] mat = new int[1000001];
	static int count =0;
	public static int find(int x){
		while(x != test.mat[x]){
			x = test.mat[x];
		}
		
		return x;
	}
	public static void liangen(int x,int y){   //將結點加入到連通圖中,如果兩個點都不在連通圖中,那麼新建一個連通圖。
		if (mat[x] == 0 && mat[y] ==0){
			test.count ++;
			mat[x] = test.count;
			mat[y] = test.count;
			
		}
		else {
			if (mat[x] != 0){
				mat[y] = mat[x];
			}
			else{
				mat[x] = mat[y];
			}
		}
	}
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);
		int row = in.nextInt();
		int clo = in.nextInt();

		int k = in.nextInt();
		for (int i =0;i<=row*clo;i++){
			mat[i] = 0;
			
		}
		for (int i =0;i<k;i++){
			int x1 = in.nextInt();
			int x2 = in.nextInt(); //獲取連根座標
			test.liangen(x1, x2);
		}
		for(int i =1;i<k;i++){
			if(mat[i] == 0) count ++;
		}
		System.out.print(count);
	}
	}
發佈了97 篇原創文章 · 獲贊 5 · 訪問量 9322
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章