码迷,mamicode.com
首页 > 其他好文 > 详细

uva 816 BFS迷宫

时间:2015-05-21 22:45:31      阅读:199      评论:0      收藏:0      [点我收藏+]

标签:bfs

这是一道比较复杂的BFS迷宫问题,状态由普通的迷宫问题的坐标(x,y)变为三个变量的状态(r,c,dir)其中dir是到达(r,c)两点的方向,这个变量非常重要,导致了这题比普通的BFS迷宫问题要更加复杂。
普通BFS解法 http://blog.csdn.net/iboxty/article/details/45888923

BFS是用队列实现的,很重要并且要理解的是:每一个节点只访问一次,而且每次BFS过程都保证压入队列中的节点到起点的距离是最短的,这题也有这样的思想。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;

const char* dirs  = "NESW";
const char* turns = "FLR";
int has_edge[10][10][4][3];
string name; 
int dir_id(char c)  {return strchr(dirs,c) - dirs;}
int turn_id(char c) {return strchr(turns,c) - turns;}
int r0,c0,r1,c1,r2,c2,r,c;
char dir0;
int dir;

struct Node{
    int r,c,dir;
    //Node(int tr,int tc,int tdir):r(tr),c(tc),dir(tdir){}
};

Node p[10][10][4];
int  d[10][10][4];


const int dr[] = {-1,0,1,0}; 
const int dc[] = {0,1,0,-1};

Node walk(const Node& u,int turn){
    int dir = u.dir;
    if(turn == 1) dir = (dir+3) % 4;
    if(turn == 2) dir = (dir+1) % 4;
    Node v;
    v.r = u.r + dr[dir];
    v.c = u.c + dc[dir];
    v.dir = dir;
    return v;
} 

bool inside(int x,int y)
{
  if(x>=1&&x<=9&&y>=1&&y<=9) return true;
  return false;
}

bool input(){
    memset(has_edge,0,sizeof(has_edge));
    string guide;
    cin>>name;
    if(name == "END") return false;
    cin>>r0>>c0>>dir0>>r2>>c2;
    dir = dir_id(dir0);
    r1=r0+dr[dir_id(dir0)];
    c1=c0+dc[dir_id(dir0)];
    while(cin>>r && r!=0){
        cin>>c;
        while(cin>>guide && guide!="*"){
            int len = guide.length();
            for(int i=1;i<len;i++){
                has_edge[r][c][dir_id(guide[0])][turn_id(guide[i])] = 1;
            }
        }
    }
    return true;
}

void print_ans(Node u){
    vector<Node> nodes;
    for(;;){
        nodes.push_back(u);
        if(d[u.r][u.c][u.dir] == 0) break;
        u = p[u.r][u.c][u.dir];
    }
    Node init;
    init.r = r0;
    init.c = c0;
    init.dir = dir;
    nodes.push_back(init);

    int cnt = 0;
    for(int i = nodes.size()-1; i >= 0;i--){
        if(cnt % 10 == 0) printf(" ") ;
        cnt++;
        printf(" (%d,%d)",nodes[i].r,nodes[i].c);
        if(cnt % 10 == 0) printf("\n");
    }
    if(nodes.size() % 10 !=0) printf("\n");
}

void bfs(){
    memset(d,-1,sizeof(d));
    queue<Node> q;
    Node u;
    u.r = r1;u.c = c1;u.dir = dir;
    d[u.r][u.c][u.dir] = 0;
    q.push(u);
    while(!q.empty()){
        Node u = q.front();q.pop();
        if(u.r == r2 && u.c == c2) {print_ans(u);return;}
        for(int i=0;i<3;i++){
            Node v = walk(u,i);
            if(has_edge[u.r][u.c][u.dir][i] && inside(v.r,v.c) && d[v.r][v.c][v.dir]<0){
                d[v.r][v.c][v.dir] = d[u.r][u.c][u.dir] + 1;
                p[v.r][v.c][v.dir] = u;
                q.push(v);
            }
        }
    }
    printf("  No Solution Possible\n");
}

int main(){

    while(input()){
        cout<<name<<endl;
        bfs();
/*      for(int i=1;i<=9;i++)
        {
            for(int j=1;j<=9;j++)
            {
                for(int k=0;k<4;k++)
                {
                    for(int l=0;l<3;l++)
                    {
                        if(has_edge[i][j][k][l])
                            printf("[%d][%d][%d][%d]\n",i,j,k,l);
                    }
                }
            }}
*/      
    }

    return 0 ;
} 

uva 816 BFS迷宫

标签:bfs

原文地址:http://blog.csdn.net/iboxty/article/details/45895439

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!