hdu1010奇偶剪枝
阿新 • • 發佈:2018-12-21
題目
根據地圖,'S’為開始位置,‘D’為門的位置,’ . '為空地,'X’為牆,不能經過, 問:在指定的時間,是否能到達’門’的位置. 注意:路不可以重複經過,時間也要剛好是 t ,不能少.
思路
:還是DFS,不能用BFS,因為BFS求的是最短路徑,而此題的路徑不一定最短. 剪枝是關鍵,奇偶剪枝. 奇偶剪枝原理: 要理解奇偶剪枝,先了解一下曼哈頓距離,從一個點到達另外一個點的最短路徑長度(時間)可以根據兩點座標求出, 路徑長度(非最短)與最短路徑的長度同奇偶,它們的差一定是偶數!舉個例子,就像兩個偶數的差差是偶數,兩個個數的差也是偶數. 本題還有一個剪枝:nm-wall與t的關係,wall為’X’的數量,解釋一下,n
import java.util.Scanner;
/**
* hdu Tempter of the Bone
* 奇偶剪枝dfs
* Created by Administrator on 2018/11/12.
*/
public class Solution1010 {
static int[][] move={{1,0},{-1,0},{0,1},{0,-1}};
private static boolean findPath(char[][]map,int sx,int sy,int ex,int ey,int n,int m,int t){
if (t==0){
return map[sx][sy]=='D';
}
int dis=t-Math.abs(sx-ex)-Math.abs(sy-ey);
if(dis<0||(dis&1)==1){
return false;
}
char tmp=map[sx][sy];
map[sx][sy]='X';
for (int i=0;i<4;i++){
int dx=sx+move[i][0],dy= sy+move[i][1];
if(0<=dx&&dx<n&&0<=dy&&dy<m&&t>=1&&map[dx][dy]!='X'){
if(findPath(map,dx,dy,ex,ey,n,m,t-1))
return true;
}
}
map[sx][sy]=tmp;
return false;
}
public static void main(String[] args) {
int n,m,t,sx=0,sy=0,ex=0,ey=0,wall;
char[][] map=new char[10][10];
Scanner in=new Scanner(System.in);
n=in.nextInt();
m=in.nextInt();
t=in.nextInt();
while (n!=0&&m!=0&&t!=0){
wall=0;
for (int i=0;i<n;i++){
String str=in.next();
for (int j=0;j<m;j++){
map[i][j]=(char)str.charAt(j);
if (map[i][j]=='S'){
sx=i;sy=j;
}if (map[i][j]=='D'){
ex=i;ey=j;
}else if (map[i][j]=='X'){
wall++;
}
}
}
if (n*m-wall<=t||!findPath(map,sx,sy,ex,ey,n,m,t)){
System.out.println("NO");
}else {
System.out.println("YES");
}
n=in.nextInt();
m=in.nextInt();
t=in.nextInt();
}
}
}