ACM HDOJ 1010 (Tempter of the Bone)

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1010

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner scn = new Scanner(System.in);
		while (scn.hasNext()) {
			int height = Integer.parseInt(scn.next());
			int width = Integer.parseInt(scn.next());
			int time = Integer.parseInt(scn.next());
			if (0 == height && 0 == width && 0 == time) {
				break;
			}
			Search search = new Search(height, width, time);
			for (int i = 0; i < height; ++i) {
				String str = scn.next();
				search.setMatrixLine(i, str.toCharArray());
				for (int j = 0; j < width; ++j) {
					if ('S' == str.charAt(j)) {
						search.setStartX(i);
						search.setStartY(j);
					} else if ('D' == str.charAt(j)) {
						search.setEndX(i);
						search.setEndY(j);
					} else if ('X' == str.charAt(j)) {
						search.setWall(search.getWall() + 1);
					}
				}
			}
			if (height * width - search.getWall() <= time) {
				System.out.println("NO");
				continue;
			}
			search.beginSearch();
			if (search.isEscape()) {
				System.out.println("YES");
			} else {
				System.out.println("NO");
			}
		}
		scn.close();
	}

}

class Search {

	private final int[][] direction = { { 0, -1 }, { 0, 1 }, { 1, 0 },
			{ -1, 0 } };
	private int height;
	private int width;
	private char[][] matrix;
	private int startX;
	private int startY;
	private int endX;
	private int endY;
	private int time;
	private int wall;
	private boolean escape;

	public Search(int height, int width, int time) {
		this.height = height;
		this.width = width;
		matrix = new char[height][width];
		this.time = time;
		wall = 0;
		escape = false;
	}

	public void beginSearch() {
		matrix[startX][startY] = 'X';
		dfs(startX, startY, 0);
	}

	private void dfs(int x, int y, int count) {
		if (count == time && x == endX && y == endY) {
			escape = true;
		}
		if (escape) {
			return;
		}
		int temp = (time - count) - Math.abs(x - endX) - Math.abs(y - endY);
		if (0 > temp || 0 != temp % 2) { // 剪枝
			return;
		}
		for (int i = 0; i < 4; ++i) {
			int nextX = x + direction[i][0];
			int nextY = y + direction[i][1];
			if (0 <= nextX && nextX < height && 0 <= nextY && nextY < width
					&& matrix[nextX][nextY] != 'X') {
				matrix[nextX][nextY] = 'X';
				dfs(nextX, nextY, count + 1);
				matrix[nextX][nextY] = '.';
			}
		}
	}

	public void setMatrixLine(int line, char[] ch) {
		matrix[line] = ch;
	}

	public void setStartX(int startX) {
		this.startX = startX;
	}

	public void setStartY(int startY) {
		this.startY = startY;
	}

	public void setEndX(int endX) {
		this.endX = endX;
	}

	public void setEndY(int endY) {
		this.endY = endY;
	}

	public int getWall() {
		return wall;
	}

	public void setWall(int wall) {
		this.wall = wall;
	}

	public boolean isEscape() {
		return escape;
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值