zoukankan      html  css  js  c++  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:
    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
    ", 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;
        }
    }
    

      

  • 相关阅读:
    Eclipse的安装及汉化图解
    Intent常用使用汇总
    Android Notification (转)
    垃圾回收
    svn常见错误汇总
    位运算
    FusionCharts简单教程(一)---建立第一个FusionCharts图形
    Delphi发送邮件...
    协程库的一些笔记
    学习日记之单例模式和Effective C++
  • 原文地址:https://www.cnblogs.com/-rainbow-/p/8375782.html
Copyright © 2011-2022 走看看