POJ 1979 Red and Black
地址: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)
这里需要注意,凡是走过的瓷砖不能够被重复走过。
1 #include <stdio.h> 2 3 const int MAX_BRICK_SIZE = 20; 4 5 /*用来存储方块符号信息*/ 6 char bricks[MAX_BRICK_SIZE + 1][MAX_BRICK_SIZE + 1]; 7 int W, H; 8 9 /*递归调用的函数。 10 *假设以(i, j)为起点,则总的可以经过的黑瓷砖数为: 11 * 1 + countBricks(i-1,j) + countBricks(i+1,j) 12 * + countBricks(i,j-1) + countBricks(i,j+1) 13 * (上下左右各算一次) 14 */ 15 int countBricks(int i, int j) { 16 /*注意,i与行数H比较,j与列数W比较*/ 17 if(i < 0 || i >= H || j < 0 || j >= W) 18 return 0; 19 if(bricks[i][j] == '#') 20 return 0; 21 22 /*别忘了置当前位置为'#',表示已经经过了*/ 23 bricks[i][j] = '#'; 24 return 1 + countBricks(i-1,j) + countBricks(i+1,j) 25 + countBricks(i,j-1) + countBricks(i,j+1); 26 } 27 28 int main() 29 { 30 while(scanf("%d%d", &W, &H), !(W == 0 && H == 0)) { 31 for(int i = 0; i < H; ++i) 32 scanf("%s", bricks[i]); 33 34 for(int i = 0; i < H; ++i) 35 for(int j = 0; j < W; ++j) 36 if(bricks[i][j] == '@') 37 printf("%d/n", countBricks(i, j)); 38 } 39 40 return 0; 41 }