HOJ 1797 Red and Black

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 HW 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.

  • '.' - a black tile
  • '#' - a red tile
  • '@' - a man on a black tile(appears exactly once in a data set)

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数组保存
	输入,由起始点开始搜索,已经拓展过的点置为“@”即可。
实现:
  • 广搜只需要将起始点加入空队列中,从队列头开始进行拓展,每拓展一个点就将其可以达到的区域加入队列同时统计值加一即可,拓展的方式是从当前点向四个方向搜索,判断是否边界、是否可达(即map[][]值为“·”,此处将“@”定为已到点,视作不可达)
  • 深搜在图的存储上及可达性判断上与广搜相同,只是递归实现时无需队列,到达可达点时对可达点进行拓展搜索;非递归实现可预先将起始点压入栈中,从栈顶开始搜索,对达到的每个点向四个方向搜索,可达点压栈,不可达点进行计数,当不可达点为四个(即此时这一分支搜索完毕)出栈并向上层返回
  • 此处想要锻炼自己手动写队列和栈的能力,于是没有用STL,但用到了C++的泛型,结果最终的感觉是写出来的是广泛应用型的数据结构,还做不到将结构的特性提炼出来融入代码中,代码仍显得冗赘,编码能力还是有待提升

代码:

广搜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; }  

你可能感兴趣的:(HOJ 1797 Red and Black)