奇偶剪枝:
对于从起始点 s 到达 终点 e,走且只走 t 步的可达性问题的一种剪枝策略。
如下列矩阵 :
从任意 0 到达 任意 0,所需步数均为偶数,到达任意 1 ,均为奇数。反之亦然
所以有,若s走且只走 t 步可到达e,则必有t >= abs(s.x - e.x) + abs(s.y - e.y),且 (t&1) == ((abs(s.x - e.x) + abs(s.y - e.y))&1)。
否则必不可达。
#include <iostream> #include <algorithm> #include <cstdlib> #include <cstdio> #include <cstring> #include <queue> #include <cmath> #include <stack> #include <map> #pragma comment(linker, "/STACK:1024000000"); #define EPS (1e-8) #define LL long long #define ULL unsigned long long LL #define _LL __int64 #define _INF 0x3f3f3f3f #define Mod 1000000007 #define LM(a,b) (((ULL)(a))<<(b)) #define RM(a,b) (((ULL)(a))>>(b)) using namespace std; char Map[10][10]; bool mark[10][10]; struct Q { int x,y,t; }; int jx[] = {-1, 0, 1, 0}; int jy[] = { 0,-1, 0, 1}; bool dfs(int sx,int sy,int ans,int ex,int ey,int n,int m,int t) { if(ans == t) { if(sx == ex && sy == ey) return true; else return false; } else if(sx == ex && sy == ey) return false; if(((abs(ex-sx) + abs(ey-sy))&1) != ((t-ans)&1)) return false; for(int i = 0;i < 4 ; ++i) { int tx = sx+jx[i]; int ty = sy+jy[i]; if(1 <= tx && tx <= n && 1 <= ty && ty <= m && Map[tx][ty] != ‘X‘ && mark[tx][ty] == false) { mark[tx][ty] = true; if(dfs(tx,ty,ans+1,ex,ey,n,m,t) == true) return true; mark[tx][ty] = false; } } return false; } void Solve(int n,int m,int t) { int i,j; int sx,sy,ex,ey; for(i = 1;i<= n; ++i) { for(j = 1;j <= m; ++j) { if(Map[i][j] == ‘S‘) { sx = i,sy = j; } else if(Map[i][j] == ‘D‘) { ex = i,ey = j; } } } memset(mark,false,sizeof(mark)); mark[sx][sy] = true; if(dfs(sx,sy,0,ex,ey,n,m,t) == true) printf("YES\n"); else printf("NO\n"); } int main() { int n,m,t; int i; while(scanf("%d %d %d",&n,&m,&t) && (n||m||t)) { for(i = 1;i <= n ; ++i) { scanf("%s",Map[i]+1); } Solve(n,m,t); } return 0; }
HDU 1010 Tempter of Bone DFS + 奇偶剪枝,布布扣,bubuko.com
时间: 2024-11-03 21:42:13