UVa 11624 Fire!

解题思路:用两个BFS,第一个可以确定某个点着火的时间。第二个BFS搜索路径。

     要是J走到某点的时间比火烧到该点的时间短,则他可以走到该点,否则不能。

     同时对输入数据处理,更方便搜索。

     -1表示该点是墙或者已经走过,不能走。

     -2表示该点可以走

      0 ~ x表示x秒时,火能烧到该点。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<queue>
 5 using namespace std;
 6 const int maxn = 1005;
 7 int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1}, mapp[maxn][maxn];
 8 int n, m, t, sx, sy;
 9 char ch;
10 
11 struct node{
12     int x, y, step;
13 }s, e;
14 
15 queue<node> q;
16 
17 int bfs()
18 {
19     s.x = sx, s.y = sy, s.step = 1; //注意s.step 初始化为1
20     mapp[s.x][s.y] = -1; //标记为已经走过
21     q.push(s);
22 
23     while(!q.empty())
24     {
25         s = q.front();
26         q.pop();
27         
28         //题目说过走到边界就算已经走出,与前面s.step初始化为1是相对应的。
29         if(s.x == 0 || s.x == n -1 || s.y == 0 || s.y == m - 1) return s.step;
30 
31         for(int i = 0; i < 4; i++)
32         {
33             e.x = s.x + dir[i][0];
34             e.y = s.y + dir[i][1];
35             e.step = s.step + 1;
36             if(e.x < 0 || e.x >= n || e.y < 0 || e.y >= m || //越界或不是可走的点并且该处有火,则不能走
37                (mapp[e.x][e.y] != -2 && mapp[e.x][e.y] < e.step)) continue; 
38             mapp[e.x][e.y] = -1; //标记为已走过
39             q.push(e);
40         }
41     }
42     return -1; //若走遍所有的路,还是没有走到边界,则返回-1
43 }
44 
45 int main()
46 {
47     scanf("%d", &t);
48     while(t--)
49     {
50         memset(mapp, -1, sizeof(mapp)); //每个测试mapp都要初始化为-1
51         while(!q.empty()) q.pop(); //加了这步更好
52 
53         scanf("%d %d", &n, &m);
54         for(int i = 0; i < n; i++)
55         {
56             for(int j = 0; j < m; j++)
57             {
58                 scanf(" %c", &ch);
59                 if(ch == '.') mapp[i][j] = -2;
60                 else if(ch == 'F')
61                 {
62                     s.x = i, s.y = j, s.step = 0;
63                     q.push(s);
64                 }
65                 else if(ch == 'J') sx = i, sy = j;
66                 //ch == '#'时是不用处理的,因为mapp已经全部初始化为-1
67             }
68         }
69 
70         while(!q.empty())
71         {
72             s = q.front();
73             q.pop();
74 
75             for(int i = 0; i < 4; i++)
76             {
77                 e.x = s.x + dir[i][0];
78                 e.y = s.y + dir[i][1];
79                 e.step = s.step + 1;
80                 if(e.x < 0 || e.x >= n || e.y < 0 || e.y >= m || mapp[e.x][e.y] != -2) continue;
81                 mapp[e.x][e.y]  = e.step; //标记火烧到该点对应的时间
82                 q.push(e);
83             }
84         }
85 
86         int ans = bfs(); //搜索路径
87 
88         if(ans == -1) printf("IMPOSSIBLE\n"); //-1表示没有搜到可行解
89         else printf("%d\n", ans);
90     }
91     return 0;
92 }
View Code

 

posted on 2015-10-01 12:07  改写历史,倾尽天下  阅读(129)  评论(0编辑  收藏  举报

导航