4 4 5 S.X. ..X. ..XD .... 3 4 5 S.X. ..X. ...D 0 0 0
NO YES
奇偶剪枝:
现假设起点为(sx,sy),终点为(ex,ey),给定t步恰好走到终点
s
|
||||
|
|
||||
|
|
||||
|
|
||||
+
|
—
|
—
|
—
|
e
|
s
|
—
|
—
|
—
|
|
—
|
—
|
+
|
||
|
|
+
|
|||
|
|
||||
+
|
—
|
—
|
—
|
e
|
#include <iostream> #include <stdio.h> #include <string.h> #include <math.h> using namespace std; char map[1010][1010]; bool vis[1010][1010]; int n,m,k,wall; bool flag; int s[4][2] = {{0,1},{1,0},{0,-1},{-1,0}}; int sx,sy,ex,ey; void DFS(int x,int y,int count) { if(flag) return; ///边界控制 if(x < 1 || x > n || y < 1 || y > m) return; if(count == k && x == ex && y == ey)///找到终点 { flag = 1; return; } ///剪枝 ///count表示已经走的时间,temp表示还有多少时间可以走 int temp = k - count - fabs(x - ex) - fabs(y - ey);///fabs(x - ex)+fabs(y - ey)表示当前点到终点还要走的时间 if(temp < 0 || temp & 1) ///看能否到达终点,temp&1则是判断其是否偶数,根据LCY的奇偶性剪枝可得tem必须是偶数,是奇数则不行 return; for(int i = 0;i < 4;i ++) { int tx = x + s[i][0]; int ty = y + s[i][1]; if(tx < 1 || tx > n || ty < 1 || ty > m || map[tx][ty] == 'X' || vis[tx][ty]) continue; vis[tx][ty] = 1; DFS(tx,ty,count + 1); vis[tx][ty] = 0; } } int main() { while(scanf("%d%d%d",&n,&m,&k) && n&&m&&k) { wall = 0; getchar(); for(int i = 1;i <= n;i ++) { for(int j = 1;j <= m;j ++) { scanf("%c",&map[i][j]); if(map[i][j] == 'X') ++ wall; if(map[i][j] == 'S')///起点 { sx = i; sy = j; } else if(map[i][j] == 'D')///终点 { ex = i; ey = j; } } getchar(); } ///总共的点数减去墙的数量减去起点判断还可以走的是否小于k if(n*m - wall - 1 < k) { printf("NO\n"); continue; } memset(vis,0,sizeof(vis)); flag = 0; vis[sx][sy] = 1; DFS(sx,sy,0); if(flag) printf("YES\n"); else printf("NO\n"); } return 0; }