zoj(2110)Tempter of the Bone(DFS+奇偶剪枝)

剪枝很重要,可走的格数小于时间则减去,然后就是奇偶性剪枝
可以把map看成这样:
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
从为 0 的格子走一步,必然走向为 1 的格子
从为 1 的格子走一步,必然走向为 0 的格子
即:
 0 ->1或1->0 必然是奇数步
 0->0 走1->1 必然是偶数步
所以当遇到从 0 走向 0 但是要求时间是奇数的,或者, 从 1 走向 0 但是要求时间是偶数的 都可以直接判断不可达!

#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <fstream>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <stdlib.h>
using namespace std ;
const int maxn = 55;
char grid[maxn][maxn];
int vis[maxn][maxn];
int n,m,s,flag;
int sx,sy,dx,dy;
int dir[4][2] = {1,0,0,1,-1,0,0,-1};
int cango(int x,int y){
    return x>=1&&x<=n&&y>=1&&y<=m;
}
void dfs(int x,int y,int step){
    if(flag)return ;//也是一种剪枝吧,不加上这句险些TLE
    if(step == s){
        if(x == dx && y == dy)
            flag = 1;
        return;
    }
    int temp = s - step - abs(dy - y)-abs(dx - x);
    if(temp<0||temp&1)//奇偶剪枝
        return;
    for(int i = 0;i < 4;i++){
        int xx = x + dir[i][0];
        int yy = y + dir[i][1];
        if(cango(xx,yy)&&!vis[xx][yy]&&grid[xx][yy] != 'X'){
            vis[xx][yy] = 1;
            dfs(xx,yy,step+1);
            vis[xx][yy] = 0;
        }
    }
}
int main(){
    while(scanf("%d%d%d",&n,&m,&s)&&(n+m+s)){
        int wall = 0;
        for(int i = 1;i <= n;i++)
            scanf("%s",grid[i]+1);
        for(int i = 1;i <= n;i++)
            for(int j = 1;j <= m;j++){
                if(grid[i][j] == 'S'){
                    sx = i;
                    sy = j;
                }
                if(grid[i][j] == 'D'){
                    dx = i;
                    dy = j;
                }
                if(grid[i][j] == 'X') wall++;
            }
        if(n*m - wall <= s){//可能性剪枝
            printf("NO\n");
            continue;
        }
        flag = 0;
        memset(vis,0,sizeof(vis));
        vis[sx][sy] = 1;
        dfs(sx,sy,0);
        if(flag)
            printf("YES\n");
        else
            printf("NO\n");
        //for(int i = 1;i <= n;i++)
          //  printf("%s\n",grid[i]+1);
    }
    return 0 ;
}
原文地址:https://www.cnblogs.com/Roly/p/3056980.html