1. 程式人生 > >hdu1010奇偶剪枝

hdu1010奇偶剪枝

借鑑思路

題目

根據地圖,'S’為開始位置,‘D’為門的位置,’ . '為空地,'X’為牆,不能經過, 問:在指定的時間,是否能到達’門’的位置. 注意:路不可以重複經過,時間也要剛好是 t ,不能少.

思路

:還是DFS,不能用BFS,因為BFS求的是最短路徑,而此題的路徑不一定最短. 剪枝是關鍵,奇偶剪枝. 奇偶剪枝原理: 要理解奇偶剪枝,先了解一下曼哈頓距離,從一個點到達另外一個點的最短路徑長度(時間)可以根據兩點座標求出, 路徑長度(非最短)與最短路徑的長度同奇偶,它們的差一定是偶數!舉個例子,就像兩個偶數的差差是偶數,兩個個數的差也是偶數. 本題還有一個剪枝:nm-wall與t的關係,wall為’X’的數量,解釋一下,n

m為區域總數,

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(); } } }

image