There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a tile, he can move to one of four adjacent tiles. But he can't move on red tiles, he can move only on black tiles.
Write a program to count the number of black tiles which he can reach by repeating the moves described above.
Input
The input consists of multiple data sets. A data set starts with a line containing two positive integers W and H; W and H are the numbers of tiles in the x- and y- directions, respectively.W and H are not more than 20.
There are H more lines in the data set, each of which includes W characters. Each character represents the color of a tile as follows.
Output
For each data set, your program should output a line which contains the number of tiles he can reach from the initial tile (including itself).
Sample Input
6 9 ....#. .....# ...... ...... ...... ...... ...... #@...# .#..#. 11 9 .#......... .#.#######. .#.#.....#. .#.#.###.#. .#.#..@#.#. .#.#####.#. .#.......#. .#########. ........... 11 6 ..#..#..#.. ..#..#..#.. ..#..#..### ..#..#..#@. ..#..#..#.. ..#..#..#.. 7 7 ..#.#.. ..#.#.. ###.### ...@... ###.### ..#.#.. ..#.#.. 0 0
Sample Output
45 59 6 13
题目大意:
给定一个图,“·”代表通路,“#”代表墙,“@”代表初始位置,求从初始位置出发,最多可以到达多少个点(包含初始位置)
分析:
可以算是最水的搜索了,深搜或者广搜都可以达到既定目标,而且在效率上也没有多大差别,不需要剪枝。用一个二维char数组保存
输入,由起始点开始搜索,已经拓展过的点置为“@”即可。
实现:
代码:
广搜BFS
#include <cstdio> #define MAXSIZE 10000 #define MAX 20 template<class T> class QUEUE { private: T elem[MAXSIZE]; int front, rear; public: QUEUE() : front(-1), rear(-1) { } void Clear() { front = rear = -1; } bool Empty() const { return front == rear; } void Push(T x) { if (++rear >= MAXSIZE) { rear -= MAXSIZE; } if (rear != front) { elem[rear] = x; } } void Pop() { if (front != rear) { front++; front %= MAXSIZE; } } T Front() { T x; if (front + 1 < MAXSIZE) x = elem[front + 1]; else x = elem[0]; return x; } }; struct POS { int x, y; POS() { } POS(int a, int b) : x(a), y(b) { } } pos; int move[4][2] = { {-1, 0}, {1, 0}, {0, 1}, {0, -1} }; char map[MAX][MAX]; int w, h, step; void BFS() { QUEUE<POS> p; p.Push(pos); step = 1; while (!p.Empty()) { pos = p.Front(); p.Pop(); for (int i = 0; i < 4; i++) { int tx = pos.x + move[i][0], ty = pos.y + move[i][1]; if (tx >= 0 && tx < w && ty >= 0 && ty < h && map[tx][ty] == '.') { POS tmp(tx, ty); p.Push(tmp); map[tx][ty] = '@'; step++; } } } printf("%d/n", step); } int main() { while (scanf("%d%d", &w, &h) && w && h) { getchar(); for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { char c = getchar(); map[j][i] = c; if (c == '@') pos.x = j, pos.y = i; } getchar(); } BFS(); } }
深搜DFS+递归实现
#include <cstdio> #define MAX 20 struct POS { int x, y; POS() { } POS(int a, int b) : x(a), y(b) { } } pos; int move[4][2] = { {-1, 0}, {1, 0}, {0, 1}, {0, -1} }; char map[MAX][MAX]; int w, h; void DFS(POS now, int &step) { map[now.x][now.y] = '@'; for (int i = 0; i < 4; i++) { int tx = now.x + move[i][0], ty = now.y + move[i][1]; if (tx >= 0 && tx < w && ty >= 0 && ty < h && map[tx][ty] == '.') { POS tmp(tx, ty); DFS(tmp, ++step); } } } int main() { while (scanf("%d%d", &w, &h) && w && h) { int step(0); getchar(); for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { char c = getchar(); map[j][i] = c; if (c == '@') pos.x = j, pos.y = i; } getchar(); } DFS(pos, ++step); printf("%d/n", step); } return 0; }
深搜DFS+非递归实现
#include <cstdio> #define MAXSIZE 10000 #define MAX 20 template<class T> class STACK { private: T elem[MAXSIZE]; int top; public: STACK() : top(-1) { } bool Empty() const { return top == -1; } void Push(T x) { if (top < MAXSIZE - 1) { elem[++top] = x; } } T Top() { T x = elem[top]; return x; } void Pop() { if (top != -1) { top--; } } }; struct POS { int x, y; POS() { } POS(int a, int b) : x(a), y(b) { } } pos; int move[4][2] = { {-1, 0}, {1, 0}, {0, 1}, {0, -1} }; char map[MAX][MAX]; int w, h; void DFS() { int step = 1; STACK<POS> p; p.Push(pos); while (!p.Empty()) { pos = p.Top(); int cnt = 0; for (int i = 0; i < 4; i++) { int tx = pos.x + move[i][0], ty = pos.y + move[i][1]; if (tx >= 0 && tx < w && ty >= 0 && ty < h && map[tx][ty] == '.') { POS tmp(tx, ty); step++; map[tx][ty] = '@'; p.Push(tmp); } else cnt++; } if (cnt == 4) p.Pop(); } printf("%d/n", step); } int main(int argc, char** argv) { while (scanf("%d%d", &w, &h) && w && h) { getchar(); for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { char c = getchar(); map[j][i] = c; if (c == '@') pos.x = j, pos.y = i; } getchar(); } DFS(); } return 0; }