hdu-1242 dfs+各种剪枝

思路:

可以和1010一个思路。这个抽象的说就是让你求给定图中两点的最短距离,其实dfs的题目能变化的地方就在“终点的回溯处”,在我们到达终点后,再判断一些附加的值(本题里是最短距离是否更新),从而得到答案。

这题有个坑点,就是图里'x',即守卫在的点。通常在dfs之前我们都习惯将map[cur_x][cur_y]设置成无法返回的墙,然后在调用完dfs之后再设回通路,而对于x点来说,我们应该将其设置成'x'而不是通路!不然如果the most optimal way如果是后找到的话,那么我们就会受到影响,题目的数据给的不错。。能发现这点


 

代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#define M 202
#define INF 65535
using namespace std;

int n,m;
char map[M][M]; 
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
int ans;
 
void dfs(int cx,int cy,int len) {
    int flag = 0;
    //硬条件剪枝 
    if(cx<1||cy<1||cx>n||cy>m) return;
    if(map[cx][cy] == '#') return;
    //软条件剪枝 
    if(len >= ans) return;
    if(map[cx][cy] == 'x') {
        len++;
        flag = 1;
    }
    if(map[cx][cy] == 'r') {
        ans = len<ans?len:ans;
        return;
    }
    for(int i = 0;i < 4;i++) {
        int nx = cx+dir[i][0];
        int ny = cy+dir[i][1];
        map[cx][cy] = '#';
        dfs(nx,ny,len+1);
        if(flag) map[cx][cy] = 'x';
        else map[cx][cy] = '.';
    }
}

int main()
{
    int sx,sy;
    while(cin>>n>>m)
    {
        ans = INF;
        for(int i = 1;i <= n;i++)
        {
            scanf("%s",map[i]+1);
            for(int j = 1;j <= m;j++) 
                if(map[i][j] == 'a') {
                    sx = i;
                    sy = j;
                }
        }
        dfs(sx,sy,0);
        if(ans == INF) {
            cout<<"Poor ANGEL has to stay in the prison all his life."<<endl;
            continue;
        }
        cout<<ans<<endl;
    }
    return 0;
} 

 

posted @ 2016-05-26 14:49  Miller_S  阅读(549)  评论(0编辑  收藏  举报