有限制的dfs

来源:互联网 发布:淘宝模特一个月多少钱 编辑:程序博客网 时间:2024/04/27 17:52

需要剪枝的dfs,剪枝理论难以寻找。。。

这个题目用一般的搜索无法完成,因为题目要求在指定的时间内完成,所以只好一步一步来啦,用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 需要奇数步                   从 0->0 需要偶数步                   那么设所在位置 (x,y) 与 目标位置 (dx,dy)                   如果abs(x-y)+abs(dx-dy)为偶数,则说明 abs(x-y) 和 abs(dx-dy)的奇偶性相同,需要走偶数步                   如果abs(x-y)+abs(dx-dy)为奇数,那么说明 abs(x-y) 和 abs(dx-dy)的奇偶性不同,需要走奇数步                   理解为 abs(si-sj)+abs(di-dj) 的奇偶性就确定了所需要的步数的奇偶性!!                   而 (ti-setp)表示剩下还需要走的步数,由于题目要求要在 ti时 恰好到达,那么  (ti-step) 与 abs(x-y)+abs(dx-dy) 的奇偶性必须相同                   因此 temp=ti-step-abs(dx-x)-abs(dy-y) 必然为偶数!

代码如下

#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include <iostream>#include <algorithm>#include <queue>#include <stack>using namespace std;int map[20][20],visit[20][20];int t;int n, m; int sx, sy, c, b;int dir[4][4] = {{0,1},{0,-1},{1,0},{-1,0}};bool dfs(int x, int y, int ans){        if (ans>t)            return false;        if (x == c && y == b){            if (ans == t)                return true;            else                return false;        }        int x1, y1;        for (int i = 0; i < 4; i++){            x1 = x + dir[i][0];            y1 = y + dir[i][1];            if (x1 >= 0 && x1 < n && y1 >= 0 && y1 < m && map[x1][y1] && (!visit[x1][y1])){                    visit[x1][y1] = 1;                if (dfs(x1,y1,ans+1))                    return true;                  visit[x1][y1] = 0;//不符合条件,重新设置没访问过的            }        }        return false;}int main(){    char z;    int i, j;    while(cin>>n>>m>>t){        if (n+m+t == 0)            break;        memset(map,0,sizeof(map));        memset(visit,0,sizeof(visit));        for (i = 0; i < n; i++){            for (j = 0; j < m; j++){                cin>>z;                if (z == 'S'){                    map[i][j] = 1;                    visit[i][j] = 1;                    sx = i;                    sy = j;                }                if (z == '.')                    map[i][j] = 1;                if (z == 'D'){                    map[i][j] = 1;                    c = i;                    b = j;                }            }        }        if ((t- abs(sx-sy)- abs(c-b))%2 == 1){//奇偶剪枝            printf("NO\n");            continue;        }       if (dfs(sx,sy,0)){        printf("YES\n");       }       else{        printf("NO\n");       }    }    return 0;}
原创粉丝点击