POJ1024 Tester Program

题目来源:http://poj.org/problem?id=1024

题目大意:

  有一个迷宫,迷宫的起点在(0,0)处。给定一条路径,和该迷宫墙的设置,要求验证该路径是否为唯一的最短路径,该种墙的设置中是否存在多于的墙,可结合图进行理解。

 

输入:第一行制定测试用例数。每个测试用例的第一行为两个正整数,指明迷宫的长和宽。接下来是给定的最短路径,用由L(左)R(右)U(上)D(下)组成的字符串表示。然后输入一个正整数m表示墙的个数。后接m行,每行四个整数,前两个整数和后两个整数分别组成两个坐标,表示该面墙把这两个点之间的路径隔断。

输出:若符合条件输出CORRECT否则输出INCORRECT。


Sample Input

2
8 5
RRRUULLURRRRDDRRUUU
19
0 0 0 1
1 0 1 1
2 0 2 1
2 1 3 1
3 0 4 0
3 1 4 1
3 2 4 2
3 2 3 3
2 2 2 3
4 2 4 3
0 3 0 4
1 3 1 4
2 3 2 4
3 3 3 4
4 3 4 4
5 3 5 4
5 3 6 3
5 2 6 2
6 1 6 2
4 3
RRRUU
2
2 2 3 2
2 2 2 1

Sample Output

CORRECT
INCORRECT

一开始没有什么想法,看了Discuss里的讨论和一些解题报告,思路很高明。

1. bfs求各点到源点的最小步数

2. bfs求各点到终点的最小步数

3. 遍历所有网格点,如果某不在路径上的点,到源点的步数+到终点的步数<=给定的路径,则给定的路径不是唯一最短

4. 检查每堵墙,如果把墙两侧点 到起点和到终点的步长加起来+1 > 给定路径的长度,则该墙多余。(如果拆掉这堵墙,唯一最短路径不变就说明多余)

  1 //////////////////////////////////////////////////////////////////////////
  2 //        POJ1024 Tester Program
  3 //        Memory: 368K        Time: 16MS
  4 //        Language: C++        Result: Accepted
  5 //////////////////////////////////////////////////////////////////////////
  6 
  7 #include <iostream>
  8 #include <string>
  9 #include <queue>
 10 using namespace std;
 11 
 12 struct Grid {
 13     bool inpath;    // 是否是路径方格
 14     bool uwal;      // 是否有上墙
 15     bool rwal;      // 是否有右墙
 16     int scnt;       // 到源点步数
 17     int dcnt;       // 到终点步数
 18 };
 19 
 20 int main(void) {
 21     bool ok;
 22     int w, h, cnt, steps;   // 1 <= w, h <= 100
 23     string path;
 24     Grid grid[100][100];
 25     queue<pair<int, int> > q;
 26 
 27     int t, x, y, desx, desy, x2, y2, i;
 28     for (cin >> t; t > 0; --t) {
 29         //初始化数据
 30         cin >> w >> h;
 31         for (y = 0; y < h; ++y) {
 32             for (x = 0; x < w; ++x) {
 33                 grid[y][x].inpath = false;
 34                 grid[y][x].uwal = false;
 35                 grid[y][x].rwal = false;
 36                 grid[y][x].scnt = -1;
 37                 grid[y][x].dcnt = -1;
 38             }
 39         }
 40         cin >> path;
 41         x = 0, y = 0;
 42         grid[0][0].inpath = true;
 43         steps = path.size();
 44         for (i = 0; i < steps; ++i) {
 45             switch (path[i]) {
 46             case 'U': ++y; break;
 47             case 'D': --y; break;
 48             case 'L': --x; break;
 49             case 'R': ++x; break;
 50             }
 51             grid[y][x].inpath = true;
 52         }
 53         desx = x, desy = y;
 54         cin >> cnt;
 55         for (i = 0; i < cnt; ++i) {
 56             cin >> x >> y >> x2 >> y2;
 57             if (x == x2)
 58                 if (y + 1 == y2) grid[y][x].uwal = true;
 59                 else grid[y2][x].uwal = true;
 60             else
 61                 if (x + 1 == x2) grid[y][x].rwal = true;
 62                 else grid[y][x2].rwal = true;
 63         }
 64 
 65         //求各点到源点的最小步数(BFS)
 66         q.push(make_pair(0, 0));
 67         grid[0][0].scnt = 0;
 68         while (!q.empty()) {
 69             y = q.front().first, x = q.front().second;
 70             if (y < h - 1 && grid[y][x].uwal == false && grid[y + 1][x].scnt == -1) {
 71                 grid[y + 1][x].scnt = grid[y][x].scnt + 1;
 72                 q.push(make_pair(y + 1, x));
 73             }
 74             if (0 < y && grid[y - 1][x].uwal == false && grid[y - 1][x].scnt == -1) {
 75                 grid[y - 1][x].scnt = grid[y][x].scnt + 1;
 76                 q.push(make_pair(y - 1, x));
 77             }
 78             if (0 < x && grid[y][x - 1].rwal == false && grid[y][x - 1].scnt == -1) {
 79                 grid[y][x - 1].scnt = grid[y][x].scnt + 1;
 80                 q.push(make_pair(y, x - 1));
 81             }
 82             if (x < w - 1 && grid[y][x].rwal == false && grid[y][x + 1].scnt == -1) {
 83                 grid[y][x + 1].scnt = grid[y][x].scnt + 1;
 84                 q.push(make_pair(y, x + 1));
 85             }
 86             q.pop();
 87         }
 88 
 89         //求各点到终点的最小步数(BFS)
 90         q.push(make_pair(desy, desx));
 91         grid[desy][desx].dcnt = 0;
 92         while (!q.empty()) {
 93             y = q.front().first, x = q.front().second;
 94             if (y < h - 1 && grid[y][x].uwal == false && grid[y + 1][x].dcnt == -1) {
 95                 grid[y + 1][x].dcnt = grid[y][x].dcnt + 1;
 96                 q.push(make_pair(y + 1, x));
 97             }
 98             if (0 < y && grid[y - 1][x].uwal == false && grid[y - 1][x].dcnt == -1) {
 99                 grid[y - 1][x].dcnt = grid[y][x].dcnt + 1;
100                 q.push(make_pair(y - 1, x));
101             }
102             if (0 < x && grid[y][x - 1].rwal == false && grid[y][x - 1].dcnt == -1) {
103                 grid[y][x - 1].dcnt = grid[y][x].dcnt + 1;
104                 q.push(make_pair(y, x - 1));
105             }
106             if (x < w - 1 && grid[y][x].rwal == false && grid[y][x + 1].dcnt == -1) {
107                 grid[y][x + 1].dcnt = grid[y][x].dcnt + 1;
108                 q.push(make_pair(y, x + 1));
109             }
110             q.pop();
111         }
112 
113         //判断路径是否唯一最短,以及墙是否多余
114         ok = true;
115         for (y = 0; y < h && ok; ++y) {
116             for (x = 0; x < w && ok; ++x) {
117                 if (grid[y][x].scnt == -1 || grid[y][x].dcnt == -1)
118                     ok = false;     // 是否有封闭区域
119                 if (y < h - 1 && grid[y][x].uwal
120                     && grid[y][x].scnt + grid[y + 1][x].dcnt + 1 > steps
121                     && grid[y][x].dcnt + grid[y + 1][x].scnt + 1 > steps)
122                     ok = false;     // 是否上墙多余
123                 if (x < w - 1 && grid[y][x].rwal
124                     && grid[y][x].scnt + grid[y][x + 1].dcnt + 1 > steps
125                     && grid[y][x].dcnt + grid[y][x + 1].scnt + 1 > steps)
126                     ok = false;     // 是否右墙多余
127                 if (!grid[y][x].inpath && grid[y][x].scnt + grid[y][x].dcnt <= steps)
128                     ok = false;     // 是否存在更短路径或另一最短路径
129             }
130         }
131         if(ok) cout << "CORRECT" << endl;
132         else cout << "INCORRECT" << endl;
133     }
134     return 0;
135 }
View Code
posted @ 2013-07-31 20:28  小菜刷题史  阅读(676)  评论(0编辑  收藏  举报