题目:在一个n*m的迷宫中有一个轮子,轮子的每个72°的扇面被涂上一种不同的颜色。
轮子可以移动到上下左右四个方向的格子中,每次移动到相邻格子中,轮子转动72°。
每个单位时间轮子可以做两种运动:
1.移动到相邻格子;2.改变朝向,面向原来的左、右方(朝向改变90°),但不转动。
初始时轮子在'S'格子中,面向西方,并且绿色的中央接触地面,
求到达'T'格子时,还是绿色的中央接触地面的情况的最短时间。('#'的格子不能移动)
分析:bfs,搜索,最短路。状态 f(行坐标:x,列坐标:y,方向:f,接触地面的颜色:c)
求解状态f(x,y,f,c)到达的最短时间,用bfs求解即可。
每个点可能走过不只一次(方向和接触地面的颜色不同),但每个状态只能走一次。
说明:这个题目比较裸,设计好状态即可直接求解。
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
using namespace std;
typedef struct node_s{
int x,y,f,c,t;
node_s(){}
node_s( int a, int b ){x = a;y = b;}
node_s( int X, int Y, int F, int C, int T ) {
x = X;y = Y;f = F;c = C;t = T;
}
}snode;
snode Q[12520],Now;
char maps[32][32];
int visit[32][32][4][5];
/* 上右下左,编号为0123 */
int dxy[4][2] = {-1,0,0,1,1,0,0,-1};
int bfs( int n, int m, snode S, snode T )
{
memset( visit, 0 ,sizeof(visit) );
int move = 0,save = 0,xx,yy;
Q[save] = snode( S.x, S.y, 0, 0, 1 );
visit[Q[save].x][Q[save].y][Q[save].f][Q[save].c] = 1;
save ++;
while ( move < save ) {
Now = Q[move ++];
/*向左侧转动*/
if ( !visit[Now.x][Now.y][(Now.f+3)%4][Now.c] ) {
visit[Now.x][Now.y][(Now.f+3)%4][Now.c] = Now.t+1;
Q[save ++] = snode( Now.x, Now.y, (Now.f+3)%4, Now.c, Now.t+1 );
}
/*向右侧转动*/
if ( !visit[Now.x][Now.y][(Now.f+1)%4][Now.c] ) {
visit[Now.x][Now.y][(Now.f+1)%4][Now.c] = Now.t+1;
Q[save ++] = snode( Now.x, Now.y, (Now.f+1)%4, Now.c, Now.t+1 );
}
/*向前移动*/
xx = Now.x + dxy[Now.f][0];
yy = Now.y + dxy[Now.f][1];
if ( xx >= 0 && xx < n && yy >= 0 && yy < m )
if ( maps[xx][yy] != '#' && !visit[xx][yy][Now.f][(Now.c+1)%5] ) {
visit[xx][yy][Now.f][(Now.c+1)%5] = Now.t+1;
Q[save ++] = snode( xx, yy, Now.f, (Now.c+1)%5, Now.t+1 );
}
}
int Min = 100000;
for ( int i = 0 ; i < 4 ; ++ i )
if ( visit[T.x][T.y][i][0] && Min > visit[T.x][T.y][i][0] )
Min = visit[T.x][T.y][i][0];
if ( Min != 100000 )
printf("minimum time = %d sec\n",Min-1);
else
printf("destination not reachable\n");
return 0;
}
/* 寻找起点和终点 */
snode findS( int n, int m, char c )
{
for ( int i = 0 ; i < n ; ++ i )
for ( int j = 0 ; j < m ; ++ j )
if ( maps[i][j] == c )
return snode( i, j );
}
int main()
{
int n,m,t = 0,ans;
while ( scanf("%d%d",&n,&m) && n+m ) {
if ( t ++ ) printf("\n");
for ( int i = 0 ; i < n ; ++ i )
scanf("%s",maps[i]);
printf("Case #%d\n",t);
bfs( n, m, findS( n, m, 'S' ), findS( n, m, 'T' ) );
}
return 0;
}
测试数据:
1 3
S#T
10 10
#S.......#
#..#.##.##
#.##.##.##
.#....##.#
##.##..#.#
#..#.##...
#......##.
..##.##...
#.###...#.
#.....###T
5 5
#S#..
#.#..
#.###
#...T
#####
10 10
S.........
..........
..........
..........
..........
..........
..........
..........
..........
........T.
3 3
ST#
##.
.#.
25 25
S........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
........................T
6 6
#.#...
#.S.#.
#####.
#..#..
#T##..
......
5 10
.S........
..##.....#
..#...T...
..#.......
..#.......
15 15
S......#.......
.......#.......
......#.#....T.
......#..#.....
.....#...#.....
....#.....#...#
....#.#.#.#....
....#..#...#...
...#..##.#.#...
...#...#....#..
..#..#.#....#..
..#.#..#.....#.
.##..#.#.....#.
...#...#.....#.
#......#.......
1 10
.S.....T..
1 3
S#T
10 10
#S.......#
#..#.##.##
#.##.##.##
.#....##.#
##.##..#.#
#..#.##...
#......##.
..##.##...
#.###...#.
#.....###T
5 5
#S#..
#.#..
#.###
#...T
#####
10 10
S.........
..........
..........
..........
..........
..........
..........
..........
..........
........T.
3 3
ST#
##.
.#.
6 6
#.#...
#.S.#.
#####.
#..#..
#T##..
......
4 7
##....T
##.###.
S..###.
##.....
4 7
##.....
##.###.
S..###.
##....T
0 0