(HDU 1010) Tempter of the Bone

HDU 1010 Tempter of the Bone

思路:

小狗走n * m迷宫,从S位置到E位置,时间要正好为T, 每秒走一步,可以向上下左右四个方向走。

DFS + 剪枝:

1、当前位置[x, y],当前所用时间k, 到终点[ex, ey]的最短步数是abs(ex-x) + abs(ey-y) + k > T 则不需继续了

2、奇偶剪枝:参考博客

代码:

import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class Main{
	public static int n, m, t;
	public static boolean ans;
	public static String map[];
	public static int vis[][];
	public static int dir[][] = {{-1,0},{1,0},{0,-1},{0,1}};
	public static int s[] = new int[2];
	public static int e[] = new int[2];
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		while(in.hasNext()){
			n = in.nextInt();
			m = in.nextInt();
			t = in.nextInt();
			if(n == 0 && m == 0 && t == 0) break;
			in.nextLine();
			map = new String[n];
			vis = new int[n][m];
			for(int i = 0; i < n; i++){
				map[i] = in.nextLine();
				for(int j = 0; j < m; j++){
					if(map[i].charAt(j) == 'S'){
						s[0] = i; s[1] = j; //起始点
					}
					else if(map[i].charAt(j) == 'D'){
						e[0] = i; e[1] = j; //终点
					}
				}					
			}
			ans = false;
			vis[s[0]][s[1]] = 1; 
			dfs(s[0],s[1],0); 
			System.out.println(ans ? "YES" : "NO");
		}
	}
	
	private static void dfs(int x, int y, int k) {
//		System.out.println(x + " " + y + " " + k);
		if(x == e[0] && y == e[1] && k == t){
			ans = true;
			return ;
		}
		int step = Math.abs(e[0] - x) + Math.abs(e[1] - y);
		if(step + k > t) 
			return;
		if(step % 2 != (t - k) % 2) 
			return ;
		
		for(int i = 0; i < 4; i++){
			int x1 = x + dir[i][0];
			int y1 = y + dir[i][1];
			if(check(x1, y1)){
				vis[x1][y1] = 1;
				dfs(x1, y1, k+1);
				if(ans) 
					return ;
				vis[x1][y1] = 0;
			}
		}
	}

	private static boolean check(int x, int y) {
		if(x < 0 || x >= n || y < 0 || y >= m) return false;
		if(map[x].charAt(y) == 'X' || vis[x][y] == 1) return false;
		return true;
	}
}
原文地址:https://www.cnblogs.com/IwAdream/p/5522846.html