【问题描述】
独轮车是一种仅有一个轮子的特殊自行车。他的轮子被等分成5个扇形,分别涂上一种不同的颜色。现在有一个人骑自行车行驶在M*N的网格平面上。每个格子的大小恰好使得当车从一个格子骑到下一个格子时,轮子恰好转过一个扇形。
如下图所示,当轮子在1号格子的中心时,蓝色扇形的外弧线中线刚好于地面接触。当它移动到下一个格子(2号格子)的时候,白色扇形的外弧线于地面接触。
有些各自中有障碍,所以车子不能通过这些格子。骑车人从某个格子出发,希望用最短的时间移动到目标格。在任何一个格子上,他要么骑到下一个格子,要么左转或者右转90度。其中每项动作恰好需要1秒来完成。初始时,他面朝北且绿色扇形贴着地面。到达目标格时,也必须是绿色扇形贴着地面,但朝向无限制。如下图所示。
【输入格式】
第一行包含两个整数M和N(1<=m,n<=100),表示迷宫的行数和列数,接下来是网格的描述,用M行长度为N的字符串来表示。字符#表示一个障碍方格,其他方格均可通行。骑车人的起点用S表示,终点用T表示。
【输出格式】
输出测试数据编号和到达目标格的最短时间(单位:秒)。如果无法到达,输出“destination not reachable”。
【输入样例】
【样例1】
1 3
S#T
【样例2】
10 10
#S.......#
#..#.##.##
#.##.##.##
.#....##.#
##.##..#.#
#..#.##...
#......##.
..##.##...
#.###...#.
#.....###T
【输出样例】
【样例1】
destination not reachable
【样例2】
minimum time = 49 sec
【数据范围】
1<=m,n<=100
这道题就是棋盘BFS遍历,只不过状态多了一些,注意处理好每一个动作相应的状态的改变就可以了。
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=105;
int n,m,sx,sy,ex,ey,d[maxn][maxn][10][10],vis[maxn][maxn][10][10];
int dx[]={0,1,0,-1};//dir:E,S,W,N
int dy[]={-1,0,1,0};
char mat[maxn][maxn];
//color:green,white,blue,red,black
struct data
{
int x,y,dir,c;
};
void bfs()
{
queue<data>q;
q.push((data){sx,sy,3,0});
memset(vis,0,sizeof(vis));
d[sx][sy][3][0]=0;
vis[sx][sy][3][0]=1;
int ok=0;
data ans;
while(!q.empty())
{
data t=q.front(); q.pop();
if(t.x==ex&&t.y==ey&&t.c==0)
{
ok=1;
ans=t;
break;
}
data tt;
tt.x=t.x+dx[t.dir];
tt.y=t.y+dy[t.dir];
tt.dir=t.dir;
tt.c=(t.c+1)%5;
if(tt.x>=1&&tt.y>=1&&tt.x<=m&&tt.y<=n)
if(mat[tt.x][tt.y]!='#')
if(vis[tt.x][tt.y][tt.dir][tt.c]==0)
{
d[tt.x][tt.y][tt.dir][tt.c]=d[t.x][t.y][t.dir][t.c]+1;
vis[tt.x][tt.y][tt.dir][tt.c]=1;
q.push(tt);
}
tt.x=t.x;
tt.y=t.y;
tt.dir=(t.dir+1)%4;
tt.c=t.c;
if(tt.x>=1&&tt.y>=1&&tt.x<=m&&tt.y<=n)
if(mat[tt.x][tt.y]!='#')
if(vis[tt.x][tt.y][tt.dir][tt.c]==0)
{
d[tt.x][tt.y][tt.dir][tt.c]=d[t.x][t.y][t.dir][t.c]+1;
vis[tt.x][tt.y][tt.dir][tt.c]=1;
q.push(tt);
}
tt.x=t.x;
tt.y=t.y;
tt.dir=(t.dir-1+4)%4;
tt.c=t.c;
if(tt.x>=1&&tt.y>=1&&tt.x<=m&&tt.y<=n)
if(mat[tt.x][tt.y]!='#')
if(vis[tt.x][tt.y][tt.dir][tt.c]==0)
{
d[tt.x][tt.y][tt.dir][tt.c]=d[t.x][t.y][t.dir][t.c]+1;
vis[tt.x][tt.y][tt.dir][tt.c]=1;
q.push(tt);
}
}
if(ok) printf("minimum time = %d sec",d[ans.x][ans.y][ans.dir][ans.c]);
else printf("destination not reachable");
}
int main()
{
//freopen("1.txt","r",stdin);
//freopen("matrix.out","w",stdout);
scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++)
{
scanf("%s",mat[i]+1);
for(int j=1;j<=n;j++)
{
if(mat[i][j]=='S') sx=i,sy=j;
if(mat[i][j]=='T') ex=i,ey=j;
}
}
bfs();
return 0;
}