明明是一道水题,即使要剪枝也是很简单的.却因为一个限定条件没加卡这么久..
总结:A题时注意把所有限定条件严格加上,避免模糊不清WA了几次.
奇偶剪枝:用终点位置计算到当前位置的最短距离,其步数的奇偶性与最终到达终点频数的奇偶性相同.
所以若最少步数奇偶性与开门的时间T奇偶性不同,则说明无法在T时间到达门.
#include <iostream> #include <cmath> using namespace std; int dir[4][2] = {-1,0,0,1,1,0,0,-1}; char map[8][8]; int N,M,T; int s_x,s_y,e_x,e_y; bool flag; bool islegal(int tx,int ty) { return tx>=0&&tx<N&&ty>=0&&ty<M&&map[tx][ty]!='X'; } void DFS(int d,int x,int y) { if (d > T) return ; int tmp = T - d - abs(e_x-x) - abs(e_y-y); if (tmp < 0 || tmp & 1) return ; for(int i=0;i<4;i++) { int tx = x + dir[i][0]; int ty = y + dir[i][1]; if(islegal(tx,ty)) { if(map[tx][ty]=='D'&&d+1==T) { flag = true; return ; } if(map[tx][ty]=='.') { map[tx][ty] = 'X'; DFS(d+1,tx,ty); if(flag) return; map[tx][ty] = '.'; } } } } int main(int argc, const char *argv[]) { // freopen("input.txt","r",stdin); while(scanf("%d%d%d", &N, &M, &T) != EOF) { if (M == 0 && N == 0 && T == 0) { break; } int empty = 0; for(int i=0;i<N;i++) { scanf ("%s", map[i]); for(int j=0;j<M;j++) { if(map[i][j]=='S') { s_x = i; s_y = j; } if(map[i][j]=='D') { e_x = i; e_y = j; } if(map[i][j]=='.') empty++; } } if(empty+1 < T) { cout<<"NO"<<endl; continue; } flag = false; DFS(0,s_x,s_y); if(flag) { cout<<"YES"<<endl; }else { cout<<"NO"<<endl; } } return 0; }