描述:
独轮车的轮子上有红、黄、蓝、白、绿(依顺时针序)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<stdio.h>
#include<iostream>
#include<queue>
using namespace std;
//chs为输入的整型数据,used数组用来记录步数并判重。
int chs[4],used[22][22][4][5]={0};
//cs[4]为输入的字符型数据,duru为输入的地图,边框的一列用来防止数组越界。
char cs[4],duru[22][22];
queue<int>q1;
queue<int>q2;
queue<int>q3;
queue<int>q4;
int flag=0;
int bug1,bug2;
void readdata();
void init();
int bfs();
int main()
{
int result;
readdata();
init();
result=bfs();
if(chs[0]==3)
{
result=result-3;
}
else
{
result--;
}
cout<<result<<endl;
return 0;
}
void readdata()
{
int i,j;
cin>>chs[0]>>chs[1];
bug1=chs[0];
bug2=chs[1];
cin>>cs[0]>>cs[1];
cin>>chs[2]>>chs[3];
cin>>cs[2];
for(i=1; i<21; i++)
{
for(j=1; j<21; j++)
{
cin>>duru[i][j];
}
}
i=0;
j=0;
while(j<22)
//边框用X表示,不能走。
{
duru[0][j]='X';
duru[21][j]='X';
j++;
}
while(i<22)
{
duru[i][0]='X';
duru[i][21]='X';
i++;
}
if(cs[2]=='R');
{
flag=0;
}
if(cs[2]=='Y')
{
flag=1;
}
if(cs[2]=='B')
{
flag=2;
}
if(cs[2]=='W')
{
flag=3;
}
if(cs[2]=='G')
{
flag=4;
}
}
void init()
{
int tmp,num;
q1.push(chs[0]);
q2.push(chs[1]);
//颜色同0,1,2,3,4,5表示,方向用,1,2,3表示。
if(cs[0]=='R')
//0表示红色。
{
tmp=0;
}
else if(cs[0]=='Y')
//1表示黄色。
{
tmp=1;
}
else if(cs[0]=='B')
//2表示蓝色
{
tmp=2;
}
else if(cs[0]=='W')
//3表示白色
{
tmp=3;
}
else if(cs[0]=='G')
{
tmp=4;
}
if(cs[1]=='E')
//0表示此时方向向东
{
num=0;
}
else if(cs[1]=='S')
//1表示此时方向向南。
{
num=1;
}
else if(cs[1]=='W')
//2表示此时方向向西
{
num=2;
}
else if(cs[1]=='N')
//3表示此时方向向北。
{
num=3;
}
//方向和颜色分别占据used数组的第三位和四位。
used[bug1][bug2][num][tmp]=1;
q3.push(num);
q4.push(tmp);
}
int bfs()
{
int a,b,c,d,A,B,C,D;
int i;
while(!q1.empty())
{
a=q1.front();
q1.pop();
b=q2.front();
q2.pop();
c=q3.front();
q3.pop();
d=q4.front();
q4.pop();
if(a==chs[2]&&b==chs[3]&&d==flag)//和目标状态相等则返回。
{
return used[a][b][c][d];
}
for(i=0; i<3; i++)
//分三种情况,0表示向前走一步,1表示向左转,2表示向右转。
{
if(i==0)
{
if(c==0&&duru[a][b+1]=='.')//c=0表示向东,则向东走一步。
{
D=(d+1)%5; // 颜色变化一
B=b+1;
//纵坐标加一。
if(used[a][B][c][D]==0)
//判重
{
used[a][B][c][D]=used[a][b][c][d]+1;
q1.push(a);
q2.push(B);
q3.push(c);
q4.push(D);
}
}
else if(c==1&&duru[a-1][b]=='.')//c=1表示向南
{
D=(d+1)%5;
A=a-1;
if(used[A][b][c][D]==0)
{
used[A][b][c][D]=used[a][b][c][d]+1;
q1.push(A);
q2.push(b);
q3.push(c);
q4.push(D);
}
}
else if(c==2&&duru[a][b-1]=='.')
{
D=(d+1)%5;
B=b-1;
if(used[a][B][c][D]==0)
{
used[a][B][c][D]=used[a][b][c][d]+1;
q1.push(a);
q2.push(B);
q3.push(c);
q4.push(D);
}
}
else if(c==3&&duru[a+1][b]=='.')
{
D=(d+1)%5;
A=a+1;
if(used[A][b][c][D]==0)
{
used[A][b][c][D]=used[a][b][c][d]+1;
q1.push(A);
q2.push(b);
q3.push(c);
q4.push(D);
}
}
}
if(i==1)//向左转
{
if(c==0)
{
C=3;
}
else
{
C=c-1;
}
if(used[a][b][C][d]==0)
{
used[a][b][C][d]=used[a][b][c][d]+1;
q1.push(a);
q2.push(b);
q3.push(C);
q4.push(d);
}
}
if(i==2)//向右转。
{
if(c==3)
{
C=0;
}
else
{
C=c+1;
}
if(used[a][b][C][d]==0)
{
used[a][b][C][d]=used[a][b][c][d]+1;
q1.push(a);
q2.push(b);
q3.push(C);
q4.push(d);
}
}
}
}
return 0;
}