HDU 1010 —— Tempter of the Bone DFS+剪枝

来源:互联网 发布:淘宝网卖家版怎么下载 编辑:程序博客网 时间:2024/05/03 15:30

原题:http://acm.hdu.edu.cn/showproblem.php?pid=1010

题意:从S走到D,其中X是墙,不能走;给定时间 t ,问能否从S到D正好花费 t 时间(一步即为一秒);

思路:用DFS+剪枝;


此处有两种剪枝:

1、从S到D的最短时间是 tmp = abs(sx-dx)+abs(sy-dy),如果 tmp > t,显然是“NO”;

2、如果 tmp <= t,那么我们要走到D就要往回走几步,如果你往左多走了一步,那么势必就要往右也走一步,才能又回到D;所以剩余步数 cnt = t - tmp 就一定是偶数;

上述的第2种剪枝方法叫做“奇偶性剪枝”;



#include<bits/stdc++.h>using namespace std;const int maxn = 10;int n, m, t;string Map[maxn];int sx, sy, dx, dy;bool flag;bool vis[maxn][maxn];void DFS(int x, int y, int step){    if(x < 0 || x >= n || y < 0 || y >= m)   return;    if(x == dx && y == dy){        if(step == t)   flag = true;        return;    }    if(x-1 >= 0 && Map[x-1][y] != 'X' && !vis[x-1][y]){        vis[x-1][y] = true;        DFS(x-1, y, step+1);        vis[x-1][y] = false;    }    if(flag)    return;    if(Map[x+1][y] != 'X' && x+1 < n && !vis[x+1][y]){        vis[x+1][y] = true;        DFS(x+1, y, step+1);        vis[x+1][y] = false;    }    if(flag)    return;    if(y-1 >= 0 && Map[x][y-1] != 'X' && !vis[x][y-1]){        vis[x][y-1] = true;        DFS(x, y-1, step+1);        vis[x][y-1] = false;    }    if(flag)    return;    if(Map[x][y+1] != 'X' && y+1 < m && !vis[x][y+1]){        vis[x][y+1] = true;        DFS(x, y+1, step+1);        vis[x][y+1] = false;    }    return;}int main(){    while(cin>>n>>m>>t){        memset(vis, false, sizeof vis);        if(n == 0 && m == 0 && t == 0)  break;        for(int i = 0;i<n;i++){            cin>>Map[i];            for(int j = 0;j<m;j++){                if(Map[i][j] == 'S')    sx = i, sy = j;                if(Map[i][j] == 'D')    dx = i,  dy = j;            }        }        int tmp = abs(sx-dx)+abs(sy-dy);        if(tmp > t || (t-tmp) % 2 != 0){            cout<<"NO"<<endl;            continue;        }        flag = false;        vis[sx][sy] = true;        DFS(sx, sy, 0);        if(flag)    cout<<"YES"<<endl;        else    cout<<"NO"<<endl;    }    return 0;}


0 0
原创粉丝点击