1. 程式人生 > >歷屆試題-和根植物

歷屆試題-和根植物

pre brush urn ins fin ear i+1 它的 out

技術分享圖片

問題描述   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:
import java.util.Scanner;

public class Main {
	//	public List<int[]> list =  new ArrayList<int[]>();
	public int[][] list;
	public int[] juzhen;
	public int index = 0;
	public int find(){
		
		int count = 0;
		while(index < juzhen.length){
			for(int i = 0;i<juzhen.length;i++){
				if(juzhen[i] == 0){
					set(i);
					break;
				}
			}
			count++;
		}
		System.out.println(count);
		return 0;
	}

	public void set(int index_x){

		if(juzhen[index_x] == 0){
			juzhen[index_x] = 1;
			index++;
			for(int i = 0;i<list[index_x].length;i++){
				if(list[index_x][i] != -1 ){
					set(list[index_x][i]);
				}
			}
		}
		return ;
	}

	public static void main(String[] args) {

		Scanner input = new Scanner(System.in);
		int m = input.nextInt(); int n = input.nextInt();
		int[] juzhen = new int[m*n];
		Main main = new Main();
		int k = input.nextInt();
		main.list = new int[m*n][4];
		for(int i = 0;i<m*n;i++){
			int[] list = {-1,-1,-1,-1};
			juzhen[i] = 0;
			main.list[i] = list;
		}
		for(int i = 0;i<k;i++){
			int index = input.nextInt();
			int page = input.nextInt();

			if(page == index-n){
				main.list[index-1][0] = page-1;
				main.list[page-1][2] = index-1;
			}else if(page == index+1){
				main.list[index-1][1] = page-1;
				main.list[page-1][3] = index-1;
			}else if(page == index+n){
				main.list[index-1][2] = page-1;
				main.list[page-1][0] = index-1;
			}else {
				main.list[index-1][3] = page-1;
				main.list[page-1][1] = index-1;
			}
		}
		main.juzhen = juzhen;
		
		main.find();
	}

}

  

c++:
#include<stdio.h>

typedef struct node{
    int num;            //當前植物的編號 
    struct node *Up;    //當前植物上面鏈接的植物 
    struct node *Down;    //當前植物下面鏈接的植物 
    struct node *Left;    //當前植物左面鏈接的植物 
    struct node *Right;    //當前植物右面鏈接的植物 
}Node;

void init( Node *, int );
void input( Node *, int , int );
void insert( Node *, int, int, int );
void search( Node *, int, int *, int );
void change( Node *, int * );

int main(void){
    int m, n, k, point=0;
    scanf("%d%d%d", &m, &n, &k );
    
    Node tree[m*n];                    //創建擁有m*n個合根植物的tree結構體數組 
    init( tree, m*n );                //初始化tree結構體數組 
    input( tree, k , n );            //輸入合根植物連根的情況 
    
    search( tree, m*n, &point, 0 );    //開始搜索合根植物數 
    
    printf("%d\n", point );
    return 0;
}

void change( Node *root, int *ch ){
    ch[root->num - 1] = 1;                                    //更新檢測數組 
    if( root->Up != NULL && ch[root->Up->num - 1] == 0 ){    //分別向四個方向搜索是否有連根情況 
        change( root->Up, ch );
    }
    if( root->Down != NULL && ch[root->Down->num - 1] == 0 ){
        change( root->Down, ch );
    }
    if( root->Left != NULL && ch[root->Left->num - 1] == 0 ){
        change( root->Left, ch );
    }
    if( root->Right != NULL && ch[root->Right->num - 1] == 0 ){
        change( root->Right, ch );
    }
}

void search( Node *root, int n, int *pp, int k ){
    static int check[1000 * 1000] = {0}; //檢測數組 記錄已經搜索過的連根 
    if( k == n ){                        //搜索出口 
        return ;
    }
    if( check[k] == 0 ){                
        change( &root[k], check );        //一個新的合根植物入口,搜索到底 
        ++ *pp;                            //合根植物數量更新 
    }
    search( root, n, pp, k+1 );
}

void insert( Node *root, int head, int tail , int n ){
    if( head == tail - 1 ){
        root[head - 1].Right = &root[tail - 1];
        root[tail - 1].Left  = &root[head - 1];        
    }
    if( head == tail + 1 ){
        root[head - 1].Left  = &root[tail - 1];
        root[tail - 1].Right = &root[head - 1];        
    }
    if( head == tail - n ){
        root[head - 1].Down  = &root[tail - 1];
        root[tail - 1].Up    = &root[head - 1];        
    }
    if( head == tail + n ){
        root[head - 1].Up    = &root[tail - 1];
        root[tail - 1].Down  = &root[head - 1];        
    }
}

void input( Node *root, int k, int n ){
    int head, tail, i;
    for( i = 0 ; i < k ; i ++ ){
        scanf("%d%d", &head, &tail );
        insert( root, head, tail, n );        //更新連根情況 
    }
}

void init( Node *root, int n ){
    int i ;
    for( i = 0 ; i < n ; i ++ ){
        root[i].num = i+1;
        root[i].Up  = NULL;
        root[i].Down= NULL;
        root[i].Left= NULL;
        root[i].Right=NULL;
    }
}

  

歷屆試題-和根植物