A Dicey Problem UVA - 810 (骰子迷宫:bfs)

题目链接

题目大意:

一个骰子,给你顶面和前面。在一个起点,每次能移动到周围4格,为-1,或顶面和该位置数字一样,那么问题来了,骰子能不能走一圈回到原地,输出路径,要求最短,假设有多个最短,依照上下左右输出

分析:

迷宫类题目,和之前的UVA-816很相似,其实两道题除了移动的规则不同,其他做法都一致。

因为骰子唯一,可以打表来模拟骰子的相邻面的关系,然后结合rotate()函数便可以模拟出骰子的移动。

和uva-816相同,需要一个距离数组,记录到起点的距离。需要一个parent数组,来记录当前结点的上一个结点,用来记录路径。

bfs的时候要注意判断边界情况!!

#include <bits/stdc++.h>
using namespace std;
const int maxn = 12;
struct Node
{
    int x,y,tp,face;
    Node() {}
    Node(int _x, int _y, int _tp, int _face):
        x(_x), y(_y), tp(_tp), face(_face){}
};
int dir[5][3] = {{1,0},{-1,0},{0,1},{0,-1}};
int to[maxn][maxn], board[maxn][maxn], dis[maxn][maxn][7][7];
Node parent[maxn][maxn][7][7];
int beg, ed, r, c, tp, face;
void prepare() {
    to[5][1] = 3,to[5][3] = 6,to[5][6] = 4,to[5][4] = 1;
    to[1][5] = 4,to[1][4] = 2,to[1][2] = 3,to[1][3] = 5;
    to[2][1] = 4,to[2][4] = 6,to[2][6] = 3,to[2][3] = 1;
    to[3][1] = 2,to[3][2] = 6,to[3][6] = 5,to[3][5] = 1;
    to[4][1] = 5,to[4][5] = 6,to[4][6] = 2,to[4][2] = 1;
    to[6][2] = 4,to[6][4] = 5,to[6][5] = 3,to[6][3] = 2; 
}

Node rotate(Node u, int i) {
    Node v = u;
    v.x = u.x+dir[i][0], v.y = u.y+dir[i][1];
    if(i==0) { v.face = v.tp; v.tp = 7-u.face; }
    else if(i==1) { v.tp = v.face; v.face = 7-u.tp; }
    else if(i==2) v.tp = 7-to[v.tp][v.face];
    else v.tp = to[v.tp][v.face];
    return v;
}

bool inside(int x, int y) {
    return x>0 && y>0 && x<=r && y<=c;
}

bool feasible(Node u, Node cur) {
    if(board[u.x][u.y]==-1) return true;
    else if(board[u.x][u.y]==cur.tp) return true;
    return false;
}

void print(Node u) {
    vector<Node> vec;
    while(true) {
        vec.push_back(u);
        if(dis[u.x][u.y][u.tp][u.face]==0) break;
        u = parent[u.x][u.y][u.tp][u.face];
    }
    int cnt = 0;
    bool flag = false, f = false;
    for(int i = (int)vec.size()-1; i >= 0; i--) {
        if(cnt++%9==0) {
            if(!f) {
                cout << endl << "  ";
                f = true;
            }
            else cout << "," << endl << "  ";
            flag = false;
        }
        if(!flag) {
            cout << "(" << vec[i].x << "," << vec[i].y << ")";
            flag = true;
        }
        else cout << ",(" << vec[i].x << "," << vec[i].y << ")";
    }
    cout << ",(" << beg << "," << ed << ")";
    cout << endl;
    return;
}

void bfs() {
    queue<Node> queue1;
    dis[beg][ed][tp][face] = 0;
    queue1.push(Node(beg,ed,tp,face));
    while(!queue1.empty()) {
        Node u = queue1.front(); queue1.pop();
        for(int i = 0; i < 4; i++) {
            Node v = rotate(u, i);
            if(!feasible(v, u) || !inside(v.x,v.y)) continue;
            if(v.x==beg && v.y==ed) {
                print(u);
                return;
            }
            if(dis[v.x][v.y][v.tp][v.face]<0) {
                queue1.push(v);
                dis[v.x][v.y][v.tp][v.face] = dis[u.x][u.y][u.tp][u.face] +1;
                parent[v.x][v.y][v.tp][v.face] = u;
            }
        }
    }
    cout << "\n  No Solution Possible"<<endl;
    return;
}

bool read() {
    string str;
    cin >> str;
    memset(board, 0, sizeof(board));
    memset(dis, -1, sizeof(dis));
    memset(parent, 0, sizeof(parent));
    if(str=="END") return false;
    cout << str;
    cin >> r >> c >> beg >> ed >> tp >> face;
    for(int i = 1; i <= r; i++) {
        for(int j = 1; j <= c; j++)
            cin >> board[i][j];
    }
    return true;
}  



int main() {
    freopen("i.txt","r",stdin);
    freopen("o.txt","w",stdout); 
    prepare();
    while(read()) {
        bfs();
    }    
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值