描述
独轮车的轮子上有红、黄、蓝、白、绿(依顺时针序)5种颜色,在一个如下图所示的20*20的迷宫内每走一个格子,轮子上的颜色变化一次。独轮车只能向前推或在原地转向。每走一格或原地转向90度均消耗一个单位时间。现给定一个起点(S)和一个终点(T),求独轮车以轮子上的指定颜色到达终点所需的最短时间。
http://www.noj.cn/images/problemimages/wheel.bmp
输入
本题包含一个测例。测例中分别用一个大写字母表示方向和轮子的颜色,其对应关系为: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
这道题思路跟前几道都一样,只不过从一维二维变成了四维。但是这道题最坑爹的是,转向的时候能向逆时针转也能向顺时针转!!!我以为只能顺时针转,一直答案错误!!!气死我了QAQ
还是要好好读题,不要默认人家只向顺时针转QAQ
而且我发现在声明using namespace std后再拿time命名数组可能会编译错误。是因为有在time.h的头文件里有叫time的函数,数组和time函数重名了。虽然没有引用time.h的头文件,但是using namespace std调用了包含time函数的命名空间。
#include<iostream>
#include<stdio.h>
#include<queue>
using namespace std;
int sx,sy,tx,ty;
char sd,sc,tc;
char map[21][21];
int used[21][21][6][5]={0};
int t[21][21][6][5];
int cx[]={-1,0,1,0},cy[]={0,1,0,-1};
struct addr
{
queue<int> x;
queue<int> y;
queue<int> c;
queue<int> d;
}addr;
void init();
int dfs();
int change(char c);
int color(int uc);
int main()
{
scanf("%d %d %c %c",&sx,&sy,&sc,&sd);
scanf("%d %d %c",&tx,&ty,&tc);
for(int i=1;i<=20;i++)
{
char temp=getchar();
for(int j=1;j<=20;j++)
{
scanf("%c",&map[i][j]);
}
}
init();
int num=dfs();
printf("%d\n",num);
}
void init()
{
int i=change(sc),j=change(sd);
addr.x.push(sx);
addr.y.push(sy);
addr.c.push(i);
addr.d.push(j);
used[sx][sy][i][j]=1;
t[sx][sy][i][j]=0;
}
int dfs()
{
int ux,uy,vx,vy,uc,ud,vc,vd;
while(1)
{
ux=addr.x.front();
uy=addr.y.front();
uc=addr.c.front();
ud=addr.d.front();
addr.x.pop();
addr.y.pop();
addr.c.pop();
addr.d.pop();
for(int i=0;i<=2;i++)//0顺时针转1逆时针转2直走
{
if(i==0)
{
vx=ux;
vy=uy;
vc=uc;
vd=(ud+1)%4; //只有方向改变
}
if(i==1)
{
vx=ux;
vy=uy;
vc=uc;
vd=(ud+3)%4;//只有方向改变
}
if(i==2)
{
vx+=cx[ud];
vy+=cy[ud]; //方向不变,颜色按顺序变化,横纵坐标按原来方向变化;
vc=color(uc);
vd=ud;
}
if(vx==tx&&vy==ty&&vc==change(tc))
{
return(t[ux][uy][uc][ud]+1);
}
if(vx>=1&&vy>=1&&vx<=20&&vy<=20&&map[vx][vy]=='.'&&used[vx][vy][vc][vd]==0)
{
addr.x.push(vx);
addr.y.push(vy);
addr.c.push(vc);
addr.d.push(vd);
used[vx][vy][vc][vd]=1;
t[vx][vy][vc][vd]=t[ux][uy][uc][ud]+1;
}
}
}
}
int change(char c)//把方向和颜色的字符转换成int型
{
if(c=='N'||c=='R') return 0;
if(c=='E'||c=='Y') return 1;
if(c=='S'||c=='B') return 2;
if(c=='W'||c=='W') return 3;
if(c=='G') return 4;
}
int color(int uc)//颜色变化
{
return (uc+1)%5;
}