POJ 1979 Red and Black

本文解决了一个经典的图遍历问题——红黑问题。任务是在一个由红砖和黑砖组成的矩阵中,从指定的起点出发,计算能够到达的所有黑砖数量。采用深度优先搜索(DFS)算法实现,通过标记已访问过的黑砖来避免重复计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:

        有一块地由H行×W列砖块组成(H, W ≤ 20),砖块有红黑两种颜色,红用'#'表示,黑用'.'表示,人起始时再一块黑砖上(起始黑砖用'@'表示),砖块的布局输入时会以H×W的矩阵形式给出,只包含'#'、'.'、'@'三种符号,其中'@'只有一个,人只能沿上下左右四个方向走,并且只能走黑砖,问该人能到达的所有黑砖总数(也包括起始位置)。

        现有多个测例,测例以H, W = 0结束,对于每个测例求出人能到达的所有黑砖的个数。

题目链接

注释代码:

/*                            
 * Problem ID : POJ 1979 Red and Black
 * Author     : Lirx.t.Una                            
 * Language   : C                
 * Run Time   : 0 ms                            
 * Run Memory : 148 KB                            
*/ 

#include <stdio.h>

//最大宽度
#define	MAXW		20

//存放矩阵,用字符串存放,要留以为给'\0'
char	m[MAXW][MAXW + 1];
int		stp;//step,步数,即可以到达的黑砖的数量
int		w, h;//列数和行数

void
dfs( int y, int x ) {//朝四个方向深搜

	stp++;
	m[y][x] = '#';//找到就标记成已经搜索过,之后就不要重复计算了

	if ( x - 1 >= 0 && '.' == m[y][x - 1] ) dfs( y, x - 1 );
	if ( x + 1 < w && '.' == m[y][x + 1] ) dfs( y, x + 1 );
	if ( y - 1 >= 0 && '.' == m[y - 1][x] ) dfs( y - 1, x );
	if ( y + 1 < h && '.' == m[y + 1][x] ) dfs( y + 1, x );
}

int
main() {

	int		i, j;//计数变量
	int		find;//用于找'@'的位置

	while ( scanf("%d%d", &w, &h), w ) {

		stp = 0;

		for ( i = 0; i < h; i++ ) scanf("%s", m[i]);

		find = 0;
		for ( i = 0; i < h; i++ ) {

			for ( j = 0; j < w; j++ )
				if ( '@' == m[i][j] ) {

					find = 1;
					break;
				}

			if ( find ) break;
		}

		dfs( i, j );

		printf("%d\n", stp);
	}

	return 0;
}
无注释代码:

#include <stdio.h>

#define	MAXW		20

char	m[MAXW][MAXW + 1];
int		stp;
int		w, h;

void
dfs( int y, int x ) {

	stp++;
	m[y][x] = '#';

	if ( x - 1 >= 0 && '.' == m[y][x - 1] ) dfs( y, x - 1 );
	if ( x + 1 < w && '.' == m[y][x + 1] ) dfs( y, x + 1 );
	if ( y - 1 >= 0 && '.' == m[y - 1][x] ) dfs( y - 1, x );
	if ( y + 1 < h && '.' == m[y + 1][x] ) dfs( y + 1, x );
}

int
main() {

	int		i, j;
	int		find;

	while ( scanf("%d%d", &w, &h), w ) {

		stp = 0;

		for ( i = 0; i < h; i++ ) scanf("%s", m[i]);

		find = 0;
		for ( i = 0; i < h; i++ ) {

			for ( j = 0; j < w; j++ )
				if ( '@' == m[i][j] ) {

					find = 1;
					break;
				}

			if ( find ) break;
		}

		dfs( i, j );

		printf("%d\n", stp);
	}

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值