[Swust OJ 191]--迷宫逃离(打表搜索)

 
Time limit(ms): 1000      Memory limit(kb): 65535
 

江鸟突然想到了一个迷宫逃离的游戏,话说有三个人被困于一个n*m的迷宫里,他们三人都可以向上、向下、向左、向右四个方向进行走动,当然他们所在的初始位置没有障碍物,同时只能走到没有障碍物的格子上,现在江鸟要问你最少需要去掉多少个格子的障碍物,可以使他们三人之间两两互相可达。

Description

输入包括多组测试数据,每组测试数据第一行为两个整数n和m(2<=n,m<=100),接下来n行,每行m个字符,其中:‘w’、‘W’、‘f’分别代表那三个人;‘.’代表没有障碍物的格子,‘#’代表有障碍物的格子。

Input

每组数据输出一行。

Output
1
2
3
4
5
6
7
8
9
10
11
4 4
w...
####
.##f
W##.
4 4
w...
....
.##f
.W..
 
Sample Input
1
2
3
2
0
 
Sample Output
Hint
信息学院院赛
 
集体思路:直接打表3个人每个人到每一个点需要去掉障碍的个数,然后枚举可到达点计算最小值即可~
     具体的可以看代码内注释
代码如下:
 1 #include <iostream>

 2 #include <cstdio>

 3 #include <cstring>

 4 #include <queue>

 5 using namespace std;

 6 

 7 #define inf 0x3f3f3f3f

 8 #define maxn  110

 9 struct node{

10     int x, y;

11 };

12 int n, m;

13 node p[4];

14 char mpt[maxn][maxn];

15 int vis[maxn][maxn][4];//vis分别代表每个人到每一个点需要消掉的障碍物

16 int dir[4][2] = { 1, 0, -1, 0, 0, 1, 0, -1 };

17 

18 void bfs(int index)

19 {

20     queue<node> q;

21     node now, next;

22     now.x = p[index].x;

23     now.y = p[index].y;

24     q.push(now);

25     vis[now.x][now.y][index] = 0;

26     while (!q.empty()){

27         now = q.front();

28         q.pop();

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

30             next = now;

31             next.x += dir[i][0];

32             next.y += dir[i][1];

33             if (next.x<1 || next.x>n || next.y<1 || next.y>m) continue;

34             int tmp = vis[now.x][now.y][index];

35             if (mpt[next.x][next.y] == '#')tmp++;//遇到一个障碍物,那么此人到达这个点需要消掉的障碍物加1

36             if (tmp < vis[next.x][next.y][index]){

37                 //判断是否可以让需要消掉的障碍物更小

38                 vis[next.x][next.y][index] = tmp;

39                 q.push(next);

40             }

41         }

42     }

43 }

44 int main(){

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

46         memset(vis, inf, sizeof(vis));

47         for (int i = 1; i <= n; i++) scanf("%s", mpt[i] + 1);

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

49             for (int j = 1; j <= m; j++){

50                 if (mpt[i][j] == 'w') p[1].x = i, p[1].y = j;

51                 else if (mpt[i][j] == 'W') p[2].x = i, p[2].y = j;

52                 else if (mpt[i][j] == 'f') p[3].x = i, p[3].y = j;

53             }

54         }

55         //对每一个人计算出到每一个点需要消掉的最少障碍物

56         bfs(1);

57         bfs(2);

58         bfs(3);

59         int ans = inf;

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

61             //如果三个人两两可以到达,那么他们可以集聚在一个点,下面枚举每一个这样的点

62             for (int j = 1; j <= m; j++){

63                 int tmp = 0;

64                 for (int k = 1; k <= 3; k++) tmp += vis[i][j][k];

65                 if (mpt[i][j] == '#') tmp -= 2;//如果在一个'#'集聚,那么就会多计算2个

66                 ans = ans < tmp ? ans : tmp;

67             }

68         }

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

70     }

71     return 0;

72 }
View Code

 

你可能感兴趣的:(搜索)