搜索剪枝DFS

来源:互联网 发布:python 兄弟连 百度云 编辑:程序博客网 时间:2024/05/17 02:57


Tempter of the Bone  hdu1010


题意:给一个图,找出一个看能否能在t的时间内从S到达D点;

思路:BFS肯定不行,因为bfs找到的是最短时间的路径,无法对在t时间点到达D点进行判断;

        于是才想到了DFS,这个能把所有的情况遍历一遍的算法,虽然图的长宽只有7,但是总是超时,这次终于体会到了剪枝的博大精深,因为虽然说长宽只有7,但是用dfs走图的情况太多了,所以必须剪枝;还有标记与再标记回来;

说说这次的剪枝:

思路:剪枝+dfs

第一个剪枝我们可以想到,当剩下的步数大于剩下的时间的时候,狗是不能走到的;
 
接下来我们来第二个剪枝:
我们把map的奇偶性以01编号:
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。
也就是说,如果当前的狗所在的坐标与D的坐标奇偶性不一样,那么狗需要走奇数步。
同理,如果狗所在坐标与D的坐标奇偶性一样,那么狗需要走偶数步数。
 
也就是说,狗的坐标x、y和对2取余是它的奇偶性,Dxy和对2取余是D的奇偶性。
两个奇偶性一加再对2取余,拿这个余数去与剩下时间对2取余的余数作比较即可


#include<iostream>#include<queue>#include<cstdio>#include<cmath>#include<cstring>using namespace std;const int maxn = 10;char s[maxn][maxn];int a ,b,c,d;int n,m,k;struct Node{    int x,y;    int times;};bool ans;int derict[][2] ={    1,0,    -1,0,    0,-1,    0,1};bool vis[maxn][maxn];void dfs(int x,int y ,int t){    if(s[x][y] == 'D' && t == k)    {        ans = true;        return ;    }    if(ans)        return;    if(t > k)        return ;    if(abs(c - x) + abs(d - y) > k - t)        return;    for(int i = 0 ; i < 4; i ++)    {        int xx = x + derict[i][0];        int yy = y + derict[i][1];        if(!vis[xx][yy] && xx >= 1&& xx <= n && yy >= 1 && yy <= m && s[xx][yy] != 'X' && s[xx][yy] != 'S')        {            vis[xx][yy] = true;            dfs(xx,yy,t + 1);            vis[xx][yy] = false;        }    }    return;}int main(){    while( ~ scanf("%d%d%d",&n,&m,&k) && (n ||m ||k))    {        memset(vis,false,sizeof(vis));        ans = false;        for(int i = 1; i <= n ; i ++)            scanf("%s",s[i] + 1);        for(int i = 1; i <= n ; i ++)        {            for(int j = 1; j <= m ; j ++)            {                if(s[i][j] == 'S')                {                    a = i;                    b = j;                }                if(s[i][j] == 'D')                {                    c = i;                    d = j;                }            }        }        if(abs(a - c) + abs(b - d) > k)        {            cout << "NO" <<endl;            continue;        }        if(!(((a + b + c + d) % 2 == 0 && k % 2 == 0) || ((a + b + c + d)% 2 && k % 2)))//或者改为if((a + b + c+ d + k)%2 != 0)        {            cout << "NO" << endl;            continue;        }        dfs(a,b,0);        if(ans)            cout << "YES" << endl;        else cout << "NO" << endl;    }    return 0;}


0 0
原创粉丝点击