概述
题目链接
题目大意:
一个骰子,给你顶面和前面。在一个起点,每次能移动到周围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;
}
最后
以上就是彩色夏天为你收集整理的A Dicey Problem UVA - 810 (骰子迷宫:bfs)的全部内容,希望文章能够帮你解决A Dicey Problem UVA - 810 (骰子迷宫:bfs)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复