您的位置:首页 > 理论基础 > 数据结构算法

HOJ 1797 Red and Black

2011-03-04 22:22 225 查看
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.

'.' - 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.To
4000
p();
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;
}
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息