zoukankan      html  css  js  c++  java
  • hdu 1241 Oil Deposits

    题意:用广度优先搜索


    //c++写输入时有问题


    1)这个是深搜

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    
    /*
    map数组是用来装字符的
    n,m提高作用域,使訪问的权限变高
    dir方便广度优先搜索,由于要搜索8个方向。这样做最方便
    */
    char map[101][101];
    int n,m;
    int dir[8][2]={{-1,-1},{0,-1},{1,-1},{-1,0},{1,0},{-1,1},{0,1},{1,1}};
    
    int main(){
        void breadthFirstSearch(int x,int y);
        bool isWithinMap(int x,int y);
        while(scanf("%d%d",&m,&n)!=EOF,n+m){
            /*
            m是行指标
            n是列指标
            */
            getchar();
            for(int i=0;i<m;i++){
                scanf("%s",map[i]);
            }
            int count=0;
            for(int i=0;i<m;i++){
                for(int j=0;j<n;j++){
                    if(map[i][j]=='@'){
                        /*
                        擦掉当前点
                        */
                        breadthFirstSearch(i,j);
                        count++;
                    }
                }
            }
            printf("%d
    ",count);
        }
        return 0;
    }
    
    /*
    px-pointx
    py-pointy
    breadthFirstSearch广搜优先搜索
    */
    void breadthFirstSearch(int x,int y){
        bool isWithinMap(int x,int y);
        int px,py;
        for(int i=0;i<8;i++){
            px = x+dir[i][0];
            py = y+dir[i][1];
            if(isWithinMap(px,py)&&map[px][py]=='@'){
                /*
                1)擦掉原来的@
                2)广搜该点
                */
                map[px][py] = '*';
                breadthFirstSearch(px,py);
            }
        }
    }
    
    bool isWithinMap(int x,int y){
        if(x<0||x>=m||y<0||y>=n){
            return false;
        }
        return true;
    }
    


    2)java广搜

    import java.util.Scanner;
    
    /*
     * 使用广搜实现
     */
    public class p1241 {
    	/*
    	 * 相当于全局变量,降低内存的使用
    	 */
    	static Plot[][] plots = new Plot[101][101];
    	static Queue queue = new Queue();
    	static int dir[][] = { { -1, -1 }, { 0, -1 }, { 1, -1 }, { -1, 0 },
    			{ 1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 } };
    	static int m = 0;
    	static int n = 0;
    
    	public static void main(String[] args) {
    		Scanner sc = new Scanner(System.in);
    		int count = 0;
    		while (sc.hasNext()) {
    			/*
    			 * m控制行
    			 * n控制列
    			 */
    			m = sc.nextInt();
    			n = sc.nextInt();
    			if (m + n == 0) {
    				return;
    			}
    			for (int i = 0; i < m; i++) {
    				String str = sc.next();
    				for (int j = 0; j < n; j++) {
    					plots[i][j] = new Plot(i, j);
    					plots[i][j].ch = str.charAt(j);
    				}
    			}
    			count = 0;
    			for (int i = 0; i < m; i++) {
    				for (int j = 0; j < n; j++) {
    					if (plots[i][j].ch == '@') {
    						/*
    						 * 通过广搜把相连的油田改变成"*"
    						 * 这样就能够降低訪问次数了
    						 */
    						plots[i][j].ch = '*';
    						queue.add(plots[i][j]);
    						breadthFirthSearch();
    						count++;
    					}
    				}
    			}
    			System.out.println(count);
    		}
    	}
    
    	/*
    	 * 
    	 */
    	private static void breadthFirthSearch() {
    		Plot plot = null;
    		int px = 0;
    		int py = 0;
    		while (!queue.isEmpty()) {
    			plot = queue.pop();
    			for (int i = 0; i < 8; i++) {
    				px = plot.x + dir[i][1];
    				py = plot.y + dir[i][0];
    				if (isWithinMap(px, py) && plots[px][py].ch == '@') {
    					plots[px][py].ch = '*';
    					queue.add(plots[px][py]);
    				}
    			}
    		}
    	}
    
    	/*
    	 * x表示行值
    	 * y表示列值
    	 */
    	private static boolean isWithinMap(int x, int y) {
    		if (x < 0 || y < 0 || x >= m || y >= n) {
    			return false;
    		}
    		return true;
    	}
    
    }
    
    /*
     * plot油井
     */
    class Plot {
    	/*
    	 * 这道题思想简单化,没有写visited,parent
    	 * 你懂得。不用的变量不写才是高效的。
    	 */
    	char ch;
    	int x;
    	int y;
    
    	public Plot(int x, int y) {
    		this.x = x;
    		this.y = y;
    	}
    
    }
    
    /*
     * 建立自己的队列
     */
    class Queue {
    	final int FRONT = 0;
    	Plot[] plots;
    	int end;
    
    	/*
    	 * 最多包括100块油井
    	 */
    	public Queue() {
    		plots = new Plot[101];
    		end = 0;
    	}
    
    	/*
    	 * 入栈函数
    	 */
    	public void add(Plot plot) {
    		plots[end] = plot;
    		end++;
    	}
    
    	/*
    	 * 出栈函数 
    	 */
    	public Plot pop() {
    		if (end <= 0) {
    			return null;
    		}
    		Plot plot = plots[FRONT];
    		for (int i = 0; i < end; i++) {
    			plots[i] = plots[i + 1];
    		}
    		end--;
    		return plot;
    	}
    
    	/*
    	 * 推断栈是否为空
    	 */
    	public boolean isEmpty() {
    		if (end >= 1) {
    			return false;
    		}
    		return true;
    	}
    
    }
    




    Oil Deposits

    石油储量
    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 18046    Accepted Submission(s): 10399


    Problem Description
    The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. 
    GeoSurvComp地质调查公司负责检測地下石油资源储量。
    GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. 
    GeoSurvComp每次在一个大矩形区域中工作,创建一个网格,将土地划分为很多方形耕地


    It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil. 
    然后分别分析每个油井。使用传感设备来确定该油井是否包括石油。
    A plot containing oil is called a pocket. 
    一块油井有油着称为一块油田。
    If two pockets are adjacent, then they are part of the same oil deposit. 
    假设两块油田是相邻的,且他们是相邻的。
    Oil deposits can be quite large and may contain numerous pockets. 
    石油资源可能非常大,可能包括众多的油井。


    Your job is to determine how many different oil deposits are contained in a grid.
     你的工作是确定有多少不同的油田被包括在一个网格。


    Input
    The input file contains one or more grids. 
    输入文件包括一个或多个网格。


    Each grid begins with a line containing m and n, the number of rows and columns in the grid, separated by a single space. 
    每个网格的第一行,各自是m和n,表示网格是m行n列,每两个数字用一个空格隔开。
    If m = 0 it signals the end of the input; otherwise 1 <= m <= 100 and 1 <= n <= 100. 
    假设m=0着输入结束否着1 <= m <= 100 and 1 <= n <= 100。
    Following this are m lines of n characters each (not counting the end-of-line characters). 
    每一行有n个字符(不包含回车符)。
    Each character corresponds to one plot, and is either `*', representing the absence of oil, or `@', representing an oil pocket.
     每个字符都要相相应的油田。“*”表示没有油井。“@”表示一个油井。

    Output
    For each grid, output the number of distinct oil deposits. 
    对于每个网格,输出不同的石油资源的数量。
    Two different pockets are part of the same oil deposit 
    对于不同的油井,
    if they are adjacent horizontally, vertically, or diagonally. 
    假设在水平,垂直,斜角是相邻的。那么表示两个油井是一片油田。


    An oil deposit will not contain more than 100 pockets.
     一块油田最多包括100块油井。

    Sample Input
    1 1 * 3 5 *@*@* **@** *@*@* 1 8 @@****@* 5 5 ****@ *@@*@ *@**@ @@@*@ @@**@ 0 0
     

    Sample Output
    0 1 2 2
     

    Source

  • 相关阅读:
    SDOI2011古代朱文
    LIS 堆优化
    ZR2019 广州 游记
    LG2709 小B的询问
    [SCOI2009] 生日礼物
    [SDOI2008]沙拉公主的困惑
    [LG3396]哈希冲突
    ZROI2018.8.2 菜鸡互啄杯组队 ACM 赛
    ZROI 菜鸡互啄杯 III
    [LG4016] 负载平衡问题
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/7202868.html
Copyright © 2011-2022 走看看