UVA 816 Abbott's Revenge(2000 Final)

来源:互联网 发布:java程序员优秀简历 编辑:程序博客网 时间:2024/06/05 19:03

题意:

有一个最多包涵9*9个交叉点的迷宫。输入起点,离开起点时的朝向和终点,求一条最短路。

思路:

这个迷宫的特殊之处在于:进入一个交叉点的方向不同,那么允许出去的方式也不同。而且朝向起到了关键的作用。所以要用一个三元组(r,c,dir)表示位于(r,c)面朝dir这个状态。由于初始时第一步怎么走是确定的,因此要从X1,Y1开始BFS,而不是X0,Y0。由于要打印路径,因此要记录前驱。

#include <queue>#include <vector>#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;struct node{    int x,y;    int w;    void init(int nx, int ny, int nw){        x = nx;        y = ny;        w = nw;    }}p[10][10][4];int X0,Y0,X1,Y1,W1,SX,SY;int dir[4][3][2] ={{-1, 0, 0, -1, 0, 1},                   {0, 1, -1, 0, 1, 0},                   {1, 0, 0, 1, 0, -1},                   {0, -1, 1, 0, -1, 0}                  };///移动数组 int map[10][10][4],vis[10][10][4];int id(char c){    if(c == 'N' || c == 'F')    return 0;    else if(c == 'E' || c == 'L')   return 1;    else if(c == 'S' || c == 'R')   return 2;    else return 3;}void print(int x, int y, int w);int bfs(int x, int y, int w){    queue <node> q;    while(!q.empty())        q.pop();    node a,b;    a.init(x, y, w);    vis[a.x][a.y][a.w] = 0;    q.push(a);    while(!q.empty()){        a = q.front();        q.pop();        if(a.x == SX && a.y == SY){            print(a.x, a.y, a.w);            return 1;        }        int xx, yy, ww;        for(int i=0; i<3; i++){            xx = a.x, yy = a.y, ww = a.w;            xx += dir[a.w][i][0];            yy += dir[a.w][i][1];            if(i == 1)  ww = (ww + 3) % 4;///用数字间的关系模拟向左转            else if(i == 2) ww = (ww + 1) % 4;            b.init(xx, yy, ww);            if((map[a.x][a.y][a.w]) & (1 << i)){///a & pow(2,n)检测a的第n位是否为1,是返回正数,否则返回假                if(xx < 1 || xx > 9 || yy < 1 || yy > 9)                    continue;                if(vis[xx][yy][ww] >= 0)                    continue;                vis[xx][yy][ww] = vis[a.x][a.y][a.w] + 1;                p[xx][yy][ww] = a;///记录前驱即父亲节点以打印路径                q.push(b);            }        }    }    return 0;}void print(int x, int y, int w){///用动态数组打印路径    vector <node> v;    node a,b;    a.init(x, y, w);    v.push_back(a);    while(vis[a.x][a.y][a.w]){        a = p[a.x][a.y][a.w];        v.push_back(a);    }    a.init(X0, Y0, W1);    v.push_back(a);    int cnt = 0;    for(int i=v.size() - 1; i >=0; i--){        if(cnt % 10 == 0) cout << " ";///控制输出十列        cout << " (" << v[i].x << "," << v[i].y << ")";        if(++cnt % 10 == 0) cout << endl;    }    if(v.size() % 10)   cout << endl;}int main(){//    freopen("in.txt", "r", stdin);    char str[30];    while(cin >> str){        if(!strcmp(str, "END")) break;        cout << str << endl;        memset(map, 0, sizeof(map));        memset(vis, -1, sizeof(vis));        char c;        cin >> X0 >> Y0 >> c >> SX >> SY;        W1 = id(c);        X1 = X0 + dir[W1][0][0];        Y1 = Y0 + dir[W1][0][1];        int xx,yy;        while(cin >> xx && xx){            cin >> yy;            gets(str);            int i = 1, j = id(str[1]);            while(str[i++] != '*'){                if(str[i] == ' '){                    j = id(str[++i]);                    continue;                }                map[xx][yy][j] ^= (1 << id(str[i]));///a ^ pow(2,n)是将a的第n位取反            }        }        if(!bfs(X1, Y1, W1))    cout << "  No Solution Possible" << endl;    }    return 0;}

0 0
原创粉丝点击