时间限制:3.000秒
题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=751
就是一道BFS而已,在普通走迷宫的基础上多加了一个骰子的状态需要判断。
题意是给出一个图,每个格子上都有一个数。然后给出一个起始位置,往这个位置上放一个骰子。然后给出这个骰子的初始状态,骰子的状态由两个数字表示,分别代表骰子顶面和正前面(从二维地图从下向上看为正前)的点数。如果骰子所在格子的相邻格子的数字等于当前骰子顶面的点数相同或者-1,那么骰子就可以滚动到这个格子上,如果格子的数字为0则表示该格子无法到达。要求求出一条路,使得骰子从起点出发能再走回起点,如果不存在,输出“No Solution Possible”。
也不是很难,按照要求BFS就可以了,搜的时候记得存一下路以便最后输出,骰子状态的转换需要注意一下。
#include
#include
#include
using std::stack;
struct status {
int i, j, up, face; // 骰子当前位置和状态
int last; // 上一个状态
status() : i(0), j(0), up(0), face(0), last(-1) {}
status(const int &i, const int &j, const int &up, const int &face, const int &last) : i(i), j(j), up(up), face(face), last(last) {}
};
int R, C;
// 骰子经过移动后对应的状态
int up_up[7][7], up_face[7][7];
int down_up[7][7], down_face[7][7];
int left_up[7][7], left_face[7][7];
int right_up[7][7], right_face[7][7];
inline void prepare() {
int dice_left[7][7];
dice_left[1][2] = 4, dice_left[1][3] = 2, dice_left[1][4] = 5, dice_left[1][5] = 3;
dice_left[2][1] = 3, dice_left[2][3] = 6, dice_left[2][4] = 1, dice_left[2][6] = 4;
dice_left[3][1] = 5, dice_left[3][2] = 1, dice_left[3][5] = 6, dice_left[3][6] = 2;
dice_left[4][1] = 2, dice_left[4][2] = 6, dice_left[4][5] = 1, dice_left[4][6] = 5;
dice_left[5][1] = 4, dice_left[5][3] = 1, dice_left[5][4] = 6, dice_left[5][6] = 3;
dice_left[6][2] = 3, dice_left[6][3] = 5, dice_left[6][4] = 2, dice_left[6][5] = 4;
for(int up = 1; up <= 6; ++up) for(int face = 1; face <= 6; ++face) if(up != face && up != 7 - face) {
up_up[up][face] = face, up_face[up][face] = 7 - up;
down_up[up][face] = 7 - face, down_face[up][face] = up;
left_up[up][face] = 7 - dice_left[up][face], left_face[up][face] = face;
right_up[up][face] = dice_left[up][face], right_face[up][face] = face;
}
}
int goal_i, goal_j;
int pic[16][16];
status que[10000000];
int vis[16][16][7][7];
inline void bfs() {
memset(vis, 0, sizeof(vis));
int fro = 0, rear = 1;
while(fro < rear) {
status &cur = que[fro];
if(cur.i == goal_i && cur.j == goal_j && fro) {
stack
st;
int pt = fro;
while(pt != -1) st.push(pt), pt = que[pt].last;
for(int i = 0; !st.empty(); st.pop(), ++i) {
int t = st.top();
if(i % 9 == 0) {
if(i) printf(",\n");
printf(" (%d,%d)", que[t].i, que[t].j);
}
else printf(",(%d,%d)", que[t].i, que[t].j);
}
printf("\n");
return;
} else if(!vis[cur.i][cur.j][cur.up][cur.face]) {
vis[cur.i][cur.j][cur.up][cur.face] = true;
int &i = cur.i, &j = cur.j;
if(pic[i - 1][j] == -1 || pic[i - 1][j] == cur.up) {
que[rear].up = up_up[cur.up][cur.face], que[rear].face = up_face[cur.up][cur.face];
que[rear].i = i - 1, que[rear].j = j, que[rear].last = fro;
++rear;
}
if(pic[i + 1][j] == -1 || pic[i + 1][j] == cur.up) {
que[rear].up = down_up[cur.up][cur.face], que[rear].face = down_face[cur.up][cur.face];
que[rear].i = i + 1, que[rear].j = j, que[rear].last = fro;
++rear;
}
if(pic[i][j - 1] == -1 || pic[i][j - 1] == cur.up) {
que[rear].up = left_up[cur.up][cur.face], que[rear].face = left_face[cur.up][cur.face];
que[rear].i = i, que[rear].j = j - 1, que[rear].last = fro;
++rear;
}
if(pic[i][j + 1] == -1 || pic[i][j + 1] == cur.up) {
que[rear].up = right_up[cur.up][cur.face], que[rear].face = right_face[cur.up][cur.face];
que[rear].i = i, que[rear].j = j + 1, que[rear].last = fro;
++rear;
}
}
++fro;
}
printf(" No Solution Possible\n");
}
int main() {
prepare();
char s[100];
while(~scanf("%s", s) && strcmp(s, "END")) {
puts(s);
scanf("%d%d%d%d%d%d", &R, &C, &que[0].i, &que[0].j, &que[0].up, &que[0].face);
goal_i = que[0].i, goal_j = que[0].j;
for(int i = 0, ei = R + 2; i != ei; ++i) for(int j = 0, ej = C + 2; j != ej; ++j) pic[i][j] = 0;
for(int i = 1; i <= R; ++i) for(int j = 1; j <= C; ++j) scanf("%d", &pic[i][j]);
bfs();
}
}