1337 - The Crystal Maze
To be more exact, the maze can be modeled as an M x N 2D grid where M denotes the number of rows and N denotes the number of columns. There are three types of cells in the grid:You are in a plane and you are about to be dropped with a parasuit in a crystal maze. As the name suggests, the maze is full of crystals. Your task is to collect as many crystals as possible.
- A '#' denotes a wall, you may not pass through it.
- A 'C' denotes a crystal. You may move through the cell.
- A '.' denotes an empty cell. You may move through the cell.
Now you are given the map of the maze, you want to find where to land such that you can collect maximum number of crystals. So, you are spotting some position x, y and you want to find the maximum number of crystals you may get if you land to cell (x, y). And you can only move vertically or horizontally, but you cannot pass through walls, or you cannot get outside the maze.
Input
Input starts with an integer T (≤ 10), denoting the number of test cases.
Each case starts with a line containing three integers M, N and Q (2 ≤ M, N ≤ 500, 1 ≤ Q ≤ 1000). Each of the next M lines contains N characters denoting the maze. You can assume that the maze follows the above restrictions.
Each of the next Q lines contains two integers xi and yi (1 ≤ xi ≤ M, 1 ≤ yi ≤ N) denoting the cell where you want to land. You can assume that cell (xi, yi) is empty i.e. the cell contains '.'.
Output
For each case, print the case number in a single line. Then print Q lines, where each line should contain the maximum number of crystals you may collect if you land on cell (xi, yi).
Sample Input |
Output for Sample Input |
14 5 2..#...C#C.##..#..C#C
1 1 4 1 |
Case 1:12 |
Note
Dataset is huge, use faster I/O methods.
题目类型:记忆化搜索
算法分析:本题其实求每一个连通块中所有水晶的数量,如果对于每个查询都调用一次DFS或者是BFS会TLE,此时应该使用记忆化搜索的思想使能通过调用一次搜索算法计算出的所有节点(在同一个连通块中)的水晶数量记录下来,然后对于已经计算过的查询操作(查询的坐标在已经计算过的连通块中),则直接输出相应的记录即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
#include <iostream> #include <fstream> #include <algorithm> #include <iomanip> #include <cstring> #include <cstdio> #include <cmath> #include <map> #include <string> #include <vector> #include <stack> #include <queue> #include <set> #include <list> #include <ctime> using namespace std; const int INF = 0x7FFFFFFF; const int maxn = 600 + 66; const int dx[] = {-1, 1, 0, 0}; const int dy[] = {0, 0, -1, 1}; char ans[maxn][maxn]; bool visited[maxn][maxn]; int maxval[maxn][maxn]; int fval[1000+66]; int row, col, q; struct Node { int x, y; Node (int xx, int yy) : x (xx), y (yy) {} Node () {} }; inline bool OkMove (int x, int y) { if (x >= 0 && x <= row - 1 && y >= 0 && y <= col - 1 && !visited[x][y] && ans[x][y] != '#') return true; return false; } queue <Node> qu; void BFS (int x, int y, int flag) { int Ctot = 0; qu.push(Node (x, y)); while (!qu.empty ()) { Node temp = qu.front (); qu.pop (); if (ans[temp.x][temp.y] == 'C') Ctot++; maxval[temp.x][temp.y] = flag; int i; for (i = 0; i < 4; i++) { if (OkMove (temp.x + dx[i], temp.y + dy[i])) { int val_x = temp.x + dx[i]; int val_y = temp.y + dy[i]; visited[val_x][val_y] = true; qu.push (Node (val_x, val_y)); } } } fval[flag] = Ctot; } int main() { // freopen ("aaa.txt", "r", stdin); int t, flag = 1; scanf ("%d", &t); while (t--) { scanf ("%d%d%d", &row, &col, &q); int i; for (i = 0; i < row; i++) scanf ("%s", ans[i]); printf ("Case %d:\n", flag++); memset (visited, false, sizeof (visited)); memset (maxval, 0, sizeof (maxval)); int val_x, val_y; for (i = 0; i < q; i++) { scanf ("%d%d", &val_x, &val_y); val_x--, val_y--; if (!visited[val_x][val_y]) { visited[val_x][val_y] = true; BFS (val_x, val_y, i); } cout << fval[maxval[val_x][val_y]] << endl; } } return 0; } |
- « 上一篇:lightoj1325
- lightoj1369:下一篇 »