您的位置:首页 > 其它

POJ 1979 Red and Black

2012-08-15 19:14 507 查看
地址:http://poj.org/problem?id=1979

思路:递归

题目分析:

输入:包括多个数据集合。每个数据集合的第一行是两个整数W和H,分别表示x方向和y方向瓷砖的数量。W和H都不超过20。在接下来的H行中,每行包括W个字符。每个字符表示一块瓷砖的颜色,规则如下
‘.’:黑色的瓷砖
‘#’:白色的瓷砖
‘@’:黑色的瓷砖,并且你站在这块瓷砖上。该字符在每个数据集合中唯一出现一次
当在一行中读入的是两个零时,表示输入结束。
输出:对每个数据集合,分别输出一行,显示你从初始位置出发能到达的瓷砖数(记数时包括初始位置的瓷砖)

算法分析:

设f(x,y)为从点(x,y)出发能够走过的黑瓷砖总数,则
f(x,y) = 1+f(x-1,y)+f(x+1,y)
+f(x,y-1)+f(x,y+1)
这里需要注意,凡是走过的瓷砖不能够被重复走过。

#include <stdio.h>

const int MAX_BRICK_SIZE = 20;

/*用来存储方块符号信息*/
char bricks[MAX_BRICK_SIZE + 1][MAX_BRICK_SIZE + 1];
int W, H;

/*递归调用的函数。
*假设以(i, j)为起点,则总的可以经过的黑瓷砖数为:
* 1 + countBricks(i-1,j) + countBricks(i+1,j)
*          + countBricks(i,j-1) + countBricks(i,j+1)
* (上下左右各算一次)
*/
int countBricks(int i, int j) {
/*注意,i与行数H比较,j与列数W比较*/
if(i < 0 || i >= H || j < 0 || j >= W)
return 0;
if(bricks[i][j] == '#')
return 0;

/*别忘了置当前位置为'#',表示已经经过了*/
bricks[i][j] = '#';
return 1 + countBricks(i-1,j) + countBricks(i+1,j)
+ countBricks(i,j-1) + countBricks(i,j+1);
}

int main()
{
while(scanf("%d%d", &W, &H), !(W == 0 && H == 0)) {
for(int i = 0; i < H; ++i)
scanf("%s", bricks[i]);

for(int i = 0; i < H; ++i)
for(int j = 0; j < W; ++j)
if(bricks[i][j] == '@')
printf("%d/n", countBricks(i, j));
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: