dfs带状态改变的做法

所谓带状态改变是指:在搜索到某个位置的时候,状态发生改变,继续计算步数。

给一个例题:

蒜头君要回家,但是他家的钥匙在他的朋友花椰妹手里,他要先从花椰妹手里取得钥匙才能回到家。花椰妹告诉他:“你家的钥匙被我复制了很多个,分别放在不同的地方。”

蒜头君希望能尽快回到家中,他需要首先取得任意一把钥匙,请你帮他计算出回家所需要的最短路程。

蒜头君生活的城市可以看做是一个 n \times mn×m的网格,其中有道路有障碍,钥匙和家所在的地方可以看做是道路,可以通过。蒜头君可以在城市中沿着上下左右 44 个方向移动,移动一个格子算做走一步。

输入格式

第一行有三个整数 nn,mm。城市的地图是 nn行 mm 列。(1 \leq n,m \leq 20001n,m2000)

接下来的 nn 行,每行 mm 个字符,代表城市的地图。'.' 代表道路,'#' 代表障碍物,'S' 代表蒜头君所在的位置,'T' 代表蒜头家的位置,'P'代表钥匙的位置。除了障碍物以外,别的地方都可以通过。(题目保证蒜头君至少有一条路径可以顺利拿到钥匙并且回家)

输出格式

输出蒜头回家要走的最少步数,占一行。

样例输入

8 10
P.####.#P#
..#..#...#
..#T##.#.#
..........
..##.#####
..........
#####...##
###....S##

样例输出

21

当拿到钥匙后,进入找家的状态,,,

方法:增加一个维度,用来记录处于哪个状态。
#include<bits/stdc++.h>
using namespace std;
char mat[2005][2005];
bool vis[2][2005][2005];
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
    int n,m;
struct Node
{
    int x,y;
    int sta;
    int step;
};
int bfs(Node s)
{
    queue<Node> q;
    while(!q.empty()) q.pop();
    q.push(s);
    while(!q.empty())
    {
        Node now=q.front();
        if(now.sta==1&&mat[now.x][now.y]=='T') return now.step;
        q.pop();
        int nx,ny;
        //cout<<now.x<<"  "<<now.y<<endl;
        for(int i=0;i<4;i++)
        {
            nx=now.x+dx[i];
            ny=now.y+dy[i];
            if(nx>=0&&nx<n&&ny>=0&&ny<m)
            {
                if(!vis[now.sta][nx][ny]&&mat[nx][ny]!='#')
                {
                    Node next;
                    next.x=nx;
                    next.y=ny;
                    next.step=now.step+1;
                    if(mat[nx][ny]=='P'||now.sta==1)
                    {
                        next.sta=1;
                    }
                    else
                    {
                        next.sta=0;
                    }
                    vis[next.sta][nx][ny]=1;
                    q.push(next);
                }
            }
        }

    }
}
int main()
{

    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        scanf("%s",mat[i]);
    }
    Node s;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            if(mat[i][j]=='S')
            {
                s.x=i;
                s.y=j;
                s.sta=0;
                s.step=0;
            }
        }
    }
    memset(vis,0,sizeof(vis));
    cout<<bfs(s)<<endl;
    return 0;

}
View Code

 

posted @ 2017-02-14 21:21  超级学渣渣  阅读(525)  评论(0编辑  收藏  举报