hdu1241详解 Java广搜搞定


import java.util.Scanner;

public class Main{

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while (sc.hasNext()) {
			int m = sc.nextInt();//输入地图的行数
			int n = sc.nextInt();//输入地图的列数
			if (m == 0) {//若m=0则退出程序
				break;
			}
			// 初始化图
			Plot[][] plots = new Plot[m][n];//用来表示地图中每个点的信息
			for (int i = 0; i < m; i++) {
				String str = sc.next();  //用来接受地图
				for (int j = 0; j < n; j++) {
					//把每个点都赋值横坐标,纵坐标,和地质情况
					plots[i][j] = new Plot();
					plots[i][j].x = i;
					plots[i][j].y = j;
					plots[i][j].c = str.charAt(j);
				}
			}
			// 搜索,查看有几个图块
			int count = 0;//表示探测到的油田的片数
			for (int i = 0; i < m; i++) {
				for (int j = 0; j < n; j++) {
					//找到油田位置,并对其进行广度搜索
					if (plots[i][j].c == '@' && !plots[i][j].isVisited) {//地址为油田和没有被搜索过
						// 广搜
						PlotQue queue = new PlotQue();
						queue.add(plots[i][j]);//把上面搜索到的油田加入到队列中
						bfs(plots, queue);
						count++;
					}
				}
			}
			System.out.println(count);//输出油田的片数,即最后的结果
		}
	}

	private static void bfs(Plot[][] plots, PlotQue queue) {
		int px, py;
		int m = plots.length;
		int n = plots[0].length;
		while (!queue.isEmpty()) {//保证队列不为空
			Plot plot = queue.pop(); //弹出队列的元素
			//在该元素周围进行广度搜索
			for (int i = 0; i < 8; i++) {
				px = plot.x + dir[i][0];
				py = plot.y + dir[i][1];
				//不能越界,地质为油田和没有被搜索过
				if (px >= 0 && px < m && py >= 0 && py < n 
						&& plots[px][py].c == '@' && !plots[px][py].isVisited) {
					plots[px][py].isVisited = true;
					queue.add(plots[px][py]);
				}
			}
		}
	}

	final static int dir[][] = { { 0, -1 }, { 0, 1 }, { -1, 0 }, { 1, 0 },
			{ -1, -1 }, { 1, -1 }, { -1, 1 }, { 1, 1 } };//上,下,左,右,左上,右上,左下,右下

}
//用来每个点
class Plot {
	int x, y;//表示点的位置
	char c;  //表示点地质情况
	boolean isVisited = false; //表示该点是否被搜索过
}
 //队列
class PlotQue {
	Plot plots[];   //队列中装的元素
	final int FRONT = 0;//表示队列的第一个元素
	int end;  //用来表示队列中的元素个数,指向队列的最后一个元素
	//构造函数
	public PlotQue() {
		plots = new Plot[100];
		end = 0;
	}
	//添加元素
	public void add(Plot p) {
		plots[end] = p;// 把p加入到队列中
		end++; //元素个数加一
	}
	//弹出元素
	public Plot pop() {
		//如果队列为空,直接返回null
		if (end <= 0) {
			return null;
		}
		//弹出第一个元素
		Plot p = plots[FRONT];
		//把弹出去的元素的位置补上,所有队列元素往前面移一位
		if (end > 1) {
			for (int i = 0; i < end; i++) {
				plots[i] = plots[i + 1];
			}
		}
		end--;//元素个数减一
		return p; //返回元素p
	}
	//判断队列是否为空
	public boolean isEmpty() {
		if (end == 0) {
			return true;
		}
		return false;
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值