描述:
独轮车的轮子上有红、黄、蓝、白、绿(依顺时针序)5种颜色,在一个如下图所示的20*20的迷宫内每走一个格子,轮子上的颜色变化一次。独轮车只能向前推或在原地转向。每走一格或原地转向90度均消耗一个单位时间。现给定一个起点(S)和一个终点(T),求独轮车以轮子上的指定颜色到达终点所需的最短时间。
输入:
本题包含一个测例。测例中分别用一个大写字母表示方向和轮子的颜色,其对应关系为:E-东、S-南、W-西、N-北;R-红、Y-黄、B-蓝、W-白、G-绿。在测试数据的第一行有以空格分隔的两个整数和两个大写字母,分别表示起点的坐标S(x,y)、轮子的颜色和开始的方向,第二行有以空格分隔的两个整数和一个大写字母,表示终点的坐标T(x,y)和到达终点时轮子的颜色,从第三行开始的20行每行内包含20个字符,表示迷宫的状态。其中'X'表示建筑物,'.'表示路.
输出:
在单独的一行内输出一个整数,即满足题目要求的最短时间。
输入样例:
3 4 R N 15 17 Y XXXXXXXXXXXXXXXXXXXX X.X...XXXXXX......XX X.X.X.....X..XXXX..X X.XXXXXXX.XXXXXXXX.X X.X.XX....X........X X...XXXXX.X.XX.X.XXX X.X.XX....X.X..X.X.X X.X.X..XX...XXXX.XXX X.X.XX.XX.X....X.X.X X.X....XX.X.XX.X.X.X X.X.X.XXXXX.XX.X.XXX X.X.X.XXXXX....X...X X.X.......X.XX...X.X X.XXX.XXX.X.XXXXXXXX X.....XX.......X...X XXXXX....X.XXXXXXX.X X..XXXXXXX.XXX.XXX.X X.XX...........X...X X..X.XXXX.XXXX...XXX XXXXXXXXXXXXXXXXXXXX
输出样例:
56
#include <iostream>
#include <queue>
using namespace std;
int sx, sy, sd, sc;
int fx, fy, fc;
char maze[21][21];
int visited[21][21][5][4];
int dir[4][2]= {{-1,0}, {0,1}, {1,0}, {0,-1}};
typedef struct Node
{
int x;
int y;
int color;
int direction;
int time;
Node(int x=0, int y=0, int color=0, int direction=0, int time=0)
:x(x), y(y), color(color), direction(direction), time(time){};
}status;
int direct(char ch)
{
switch(ch)
{
case 'N':
return 0;
case 'E':
return 1;
case 'S':
return 2;
case 'W':
return 3;
}
}
int color(char ch)
{
switch(ch)
{
case 'R':
return 0;
case 'Y':
return 1;
case 'B':
return 2;
case 'W':
return 3;
case 'G':
return 4;
}
}
//直走
status toStraight(status u)
{
status v = u;
v.x = v.x+dir[u.direction][0];
v.y = v.y+dir[u.direction][1];
v.color = (v.color+1)%5;
v.time ++;
return v;
}
//右转
status toRight(status u)
{
status v = u;
v.direction = (v.direction+1)%4;
v.time ++;
return v;
}
//左转
status toLelf(status u)
{
status v = u;
v.direction = (v.direction+3)%4;
v.time ++;
return v;
}
bool isAim(status u)
{
if(u.x == fx && u.y == fy && u.color == fc)
return true;
else
return false;
}
bool isLegal(status u)
{
if(u.x > 0 && u.x < 21 && u.y > 0 && u.y < 21 && (!visited[u.x][u.y][u.color][u.direction]) && maze[u.x][u.y] == '.')
return true;
else
return false;
}
int bfs()
{
queue<Node> q;
status s = Node(sx, sy, sc, sd, 0);
q.push(s);
visited[sx][sy][sc][sd] = 1;
while(!q.empty())
{
s = q.front();
q.pop();
status v = toStraight(s);
if(isLegal(v))
{
if(isAim(v))
return v.time;
visited[v.x][v.y][v.color][v.direction] = 1;
q.push(v);
}
v = toLelf(s);
if(!visited[v.x][v.y][v.color][v.direction])
{
visited[v.x][v.y][v.color][v.direction] = 1;
q.push(v);
}
v = toRight(s);
if(!visited[v.x][v.y][v.color][v.direction])
{
visited[v.x][v.y][v.color][v.direction] = 1;
q.push(v);
}
}
return -1;
}
int main()
{
char c, d;
cin >> sx >> sy >> c >> d;
sc = color(c), sd = direct(d);
cin >> fx >> fy >> c;
fc = color(c);
for(int i = 1; i <= 20; i++)
{
for(int j = 1; j <= 20; j++)
{
cin >> maze[i][j];
}
}
cout << bfs() << endl;
return 0;
}