CSUOJ 1259 跳跳

Description

 一个每块地板标记着0~9某个数字的迷宫,其中标记1的地板不可以走,标记2~9的地板可以不花时间地跳到任意相同数字的位置,也可以和标记0的地板一样向前后左右任意方向花1个单位时间移动1的距离。给出起点和终点,求起点到终点的最短时间。

Input

 每组数据第一行一个n,表示尺寸,2 <= n <= 100。

接下来n行每行n个0~9的字符,或S表示起点,E表示终点,S和E的运动规则与0相同。整个地图只有一个S和一个E。

Output

 每组数据输出一个数,占一行,表示起点到终点可以花费的最短时间。

如果无法到达重点,输出"Oh No!"

Sample Input

5

0S100

00131

00300

00000

003E0

3

S12

010

10E

Sample Output

4

Oh No!


BFS的变形 需要注意的一点事遇到2-9的数字就全部push 相应数字

 1 # include <cstdio>

 2 # include <queue>

 3 # include <cstring>

 4 # define N 105

 5 using namespace std;

 6 

 7 int n;

 8 char g[N][N];

 9 char vis[N][N];

10 

11 struct pos{int x, y, d;};

12 queue <pos> Qst[10];

13 pos st;

14 

15 //描述相邻点的相对位置

16 const int dx[] = {0, 0, 1, -1};

17 const int dy[] = {1, -1, 0, 0};

18 

19 int bfs()

20 {

21     queue <pos> Q;

22     Q.push(st);

23     //访问标记

24     vis[st.x][st.y] = 1;

25     while(!Q.empty()){

26         pos cur = Q.front();

27         Q.pop();

28         for(int i = 0; i < 4; ++i){

29             pos nst;

30             //遍历该店上下左右的点

31             nst.x = cur.x + dx[i];

32             nst.y = cur.y + dy[i];

33             //判断是否还在范围内并且未访问过

34             if(1 <= nst.x && nst.x <= n && 1 <= nst.y && nst.y <= n && !vis[nst.x][nst.y]){

35                 //访问标记

36                 vis[nst.x][nst.y] = 1;

37                 char ch = g[nst.x][nst.y];

38                 //判断是否找到终点 找到返回步数

39                 if(ch == 'E')

40                     return cur.d+1;

41                 //判断是否遇到阻碍 是的话跳过进入下一次循环

42                 if(ch == '1')

43                     continue;

44                 //如果是 0 步数加 1 把邻接点压入队列

45                 if(ch == '0')

46                     nst.d=cur.d+1, Q.push(nst);

47                 //如果是2-9可以“传送”的点 找到与该点数字相同点压入队列

48                 else if ('2' <=ch && ch <= '9'){

49                     pos nnst;

50                     while(!Qst[ch-'0'].empty()){

51                         nnst = Qst[ch-'0'].front();

52                         Qst[ch-'0'].pop();

53                         vis[nnst.x][nnst.y] = 1;

54                         nnst.d = cur.d + 1;

55                         Q.push(nnst);

56                     }

57                 }

58             }

59         }

60     }

61     return -1;

62 }

63 

64 int main()

65 {

66     while (~scanf("%d", &n)){

67         pos tmp;

68         //将队列清空

69         for(int i = 2; i <= 9; i++)

70             while (!Qst[i].empty())

71                 Qst[i].pop();

72         for (int i = 1; i <= n; i++){

73             scanf("%s", g[i]+1);

74             memset(vis[i]+1, 0, sizeof(char)*n);

75             for(int j = 1; j <= n; j++){

76                 char ch = g[i][j];

77                 //把可跳跃位置压入队列

78                 if ('2' <= ch && ch <= '9'){

79                     tmp.x = i, tmp.y = j;

80                     Qst[ch-'0'].push(tmp);

81                 }

82                 //记录初始位置

83                 else if (ch == 'S'){

84                     st.x = i, st.y = j;

85                     st.d = 0;

86                 }

87             }

88         }

89         int ans = bfs();

90         if (ans == -1)

91             printf("Oh No!\n");

92         else

93             printf("%d\n", ans);

94     }

95     return 0;

96 }

 



你可能感兴趣的:(OJ)