比較好的搜尋題,考驗剪枝。
這裡用了三個剪枝:
1.奇偶性剪枝,題目要求確切在t這個時間點上到達目的地,而且小狗不能作停留,那麼如果給出的時間t,和起點到終點的距離奇偶性不等,則一定不可達。
2.可達性剪枝,如果從起點到終點毫不繞行要k步,地圖上能走的地方也比k步少,毫無疑問,也不可能。
3.可達性剪枝2,搜尋時可能離目標越來越遠,以致再回頭已經來不及走了,所以在搜尋到中途某個位置時,如果所剩時間比毫不繞行走到目標還小,那麼也不用再往下搜了。
話說用了三個剪枝,java照樣給我跑了700+ms,效率真不敢恭維。。
import java.util.*;<br />public class Main{</p><p>static final int MaxN = 8;<br />static char map[][] = new char[MaxN][MaxN];<br />static int n , m , t , Dx = 0 , Dy = 0;<br />static int dir[][] = {{0 , 1} , {0 , -1} , {-1 , 0} , {1 , 0}};</p><p>static boolean inMap(int r, int c){<br />return r >= 0 && c >= 0 && r < n && c < m;</p><p>}<br />static boolean DFS(int r ,int c , int d){</p><p>if (d < Math.abs(r - Dx) + Math.abs(c - Dy))return false;<br />if (d == 0){<br />if (r == Dx && c == Dy)return true;<br />return false;<br />}</p><p>map[r][c] = 'X';<br />int _r , _c , i;<br />for (i = 0;i < 4;i ++){<br />_r = r + dir[i][0];<br />_c = c + dir[i][1];<br />if (inMap(_r , _c) && map[_r][_c] != 'X'){<br />if (DFS(_r , _c , d - 1))return true;<br />}<br />}<br />map[r][c] = '.';<br />return false;</p><p>}</p><p>public static void main(String []a){</p><p>Scanner in = new Scanner(System.in);<br />String tmp = new String();<br />int i , j ,wallNum , Sx = 0 , Sy = 0;<br />while (true){<br />n = in.nextInt();<br />m = in.nextInt();<br />t = in.nextInt();<br />if (n == 0 && m == 0 && t == 0)break;</p><p>wallNum = 0;<br />for (i = 0;i < n;i ++){<br />tmp = in.next();<br />map[i] = tmp.toCharArray();<br />for (j = 0;j < m;j ++){<br />if (map[i][j] == 'S'){<br />Sx = i;Sy = j;<br />}elseif (map[i][j] == 'D'){<br />Dx = i;Dy = j;<br />}elseif (map[i][j] == 'X'){<br />wallNum ++;<br />}<br />}<br />}</p><p>if (((Sx + Sy + Dx + Dy + t) & 1) == 1 || n * m - wallNum - 1 < Math.abs(Dx - Sx) + Math.abs(Dy - Sy)){<br />System.out.println("NO");<br />continue;<br />}</p><p>if (DFS(Sx , Sy , t)){<br />System.out.println("YES");<br />}else{<br />System.out.println("NO");<br />}<br />}<br />}<br />}