POJ 1111 Image Perimeters

题目大意:

        给你一个图像,让你求图像中目标的轮廓长度,即周长。图像大小是n×m个像素点,像素点用字符表示,'.'表示空白,'X'表示目标像素点,其中一个像素点周围的8个点都是和该点相连的,如果一个目标点'X'相连的点中也有'X'则这两个'X'算在同一个目标区域当中,现在就是让你求图像中一个目标点所在的目标区域的周长。其中周长是这样定义的,就是目标区域上下左右四个方向上挨着的空白点的数量(图像边界外如果无空白点则在思考是需要加上这些空白点),如果这些白点中有重复则需要重复计数的!!!。

        现有多个测例,每个测例中都给出n、m以及起始目标点的坐标(x, y),坐标从1开始计,接下来会给出整个图像的信息,用一个n×m的矩阵表示,只含'.'和'X'两种字符,输入以n, m = 0结束,对于每个测例要求输出目标所在点的区域的周长,输入保证不含有洞,即目标区域内有空白的洞,所有的输入数据范围不超过20。

题目链接

注释代码:

/*                               
 * Problem ID : POJ 1111 Image Perimeters
 * Author     : Lirx.t.Una                               
 * Language   : C                   
 * Run Time   : 0 ms                               
 * Run Memory : 136 KB                               
*/ 

#include <memory.h>
#include <stdio.h>

//图像的最大宽度
#define	MAXN	20

char	m[MAXN + 2][MAXN + 2];//存储图像,边界以外的一周的点也需要用到
//前四个表示上向左右四个方向,后四个为四个角
char	dx[9] = { 0, 1, -1,  0,  0, 1, -1,  1, -1 };
char	dy[9] = { 0, 0,  0,  1, -1, 1, -1, -1,  1 };

int
dfs( int x, int y ) {//对(x, y)所在目标区域进行深搜

	int		sum;//边界点数
	int		i;//计数变量

	if ( 'X' != m[x][y] ) return 0;

	m[x][y] = '\0';//对访问过的点进行标记,但不能置成空白点'.'
	//以避免重复计算边界点数

	sum = 0;
	for ( i = 1; i <= 4; i++ )//先按照题目要求检测上下左右四个点
		//其空白点数都计算在周长中(都属于边界点)
		sum += '.' == m[ x + dx[i] ][ y + dy[i] ];
	for ( i = 1; i <= 8; i++ )//在对所有方向继续深搜
		sum += dfs( x + dx[i], y + dy[i] );

	return sum;
}

int
main() {

	int		i;//计数变量
	int		r, c, x, y;//行列长度以及起始目标点的坐标
	int		j;//计数变量

	while ( scanf("%d%d%d%d", &r, &c, &x, &y), r ) {
	
		//由于图像的横纵方向的范围都是从1开始计的
		//因此需要将边界以外的点都置成空白
		memset(m, '.', sizeof(m));

		for ( i = 1; i <= r; i++ ) {
		
			scanf("%s", m[i] + 1);
			m[i][c + 1] = '.';//%s输入后会补'\0',需要将其值为空白
		}

		printf("%d\n", dfs( x, y ));
	}

	return 0;
}
无注释代码:

#include <memory.h>
#include <stdio.h>

#define	MAXN	20

char	m[MAXN + 2][MAXN + 2];
char	dx[9] = { 0, 1, -1,  0,  0, 1, -1,  1, -1 };
char	dy[9] = { 0, 0,  0,  1, -1, 1, -1, -1,  1 };

int
dfs( int x, int y ) {

	int		sum;
	int		i;

	if ( 'X' != m[x][y] ) return 0;

	m[x][y] = '\0';

	sum = 0;
	for ( i = 1; i <= 4; i++ )
		sum += '.' == m[ x + dx[i] ][ y + dy[i] ];
	for ( i = 1; i <= 8; i++ )
		sum += dfs( x + dx[i], y + dy[i] );

	return sum;
}

int
main() {

	int		i;
	int		r, c, x, y;
	int		j;

	while ( scanf("%d%d%d%d", &r, &c, &x, &y), r ) {
	
		memset(m, '.', sizeof(m));

		for ( i = 1; i <= r; i++ ) {
		
			scanf("%s", m[i] + 1);
			m[i][c + 1] = '.';
		}

		printf("%d\n", dfs( x, y ));
	}

	return 0;
}
单词解释:

enclosed:adj, 被附上的,与世隔绝的

period:n, 周期

grid:n, 网格

analysis:n, 分析,验定

slide:n, 幻灯片,滑梯,雪崩

digitized:adj, 数字化的

pathology:n, 病理学

technician:n, 技师,技术员

perimeter:n, 周长

Darmstadt:n, 达姆施塔特(德国城市)

adventruous:adj, 喜欢冒险的

perpendicular:adj, 垂直的,正交的

assert:vt, 断言

fabulous:adj, 难以置信的

offer sb to:vt, 给某人提供某物或服务

tile:n, 瓷砖,瓦片

ultra:adj, 极端的,过分的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值