POJ 3923 Ugly Windows

题目大意:

        有一个矩形的图形框架,框架中有大写字母表示的矩形框架(因此矩形框架最都有26个,矩形框架只有边),矩形框架之间可以相互覆盖,被覆盖的部分不能被显示,现要求找出给定图形中的顶端窗口(即没有被任何其他矩形窗口覆盖的窗口),注意!!有些窗口在其他窗口之内也算覆盖(小的覆盖大的)。

        现有多个测例,每个测例中给定总框架的长和宽n、m(1 ≤ n, m ≤ 100),接下来就给出该图形的描绘,其中窗口用大写字母表示,非窗口的部分用'.'表示,其中保证输入有如下特点:

        1. 至少有一个窗口;

        2. 窗口的宽和长至少占3个字符;

        3. 不会有窗口在框架的外面(即屏幕外面);

        对于每个测例,要求输出顶端窗口所表示的字母,如果有多个按照字母表顺序输出,每个测例占一行,输入以n = 0结束。

题目链接

注释代码:

/*                                           
 * Problem ID : POJ 3923 Ugly Windows 
 * Author     : Lirx.t.Una                                           
 * Language   : C                          
 * Run Time   : 0 ms                                           
 * Run Memory : 136 KB                                           
*/ 

#include <stdio.h>
#include <ctype.h>

#define	TRUE	1
#define	FALSE	0

#define	INF		101

//maximum screen size
//屏幕的最大尺寸
//从下标1开始计
//所以总共最多为101个字符,加一个空字符
#define	MAXSCSIZE		102

typedef	int		BOOL;

char	 sc[MAXSCSIZE][MAXSCSIZE];//screen,屏幕

BOOL
isTop( char ch, int n, int m ) {
	//检查以字符ch所代表的是否为顶端窗口
	
	int		i, j;//计数变量
	
	//计算窗口的的横坐标和纵坐标的极值
	int		x_max, x_min;
	int		y_max, y_min;
	
	int		cnt;//count,统计该字符出现的次数
	
	//初始化
	x_max = 0;
	y_max = 0;
	
	x_min = INF;
	y_min = INF;
	
	cnt = 0;
	
	for ( i = 1; i <= n; i++ )
		for ( j = 1; j <= m; j++ )
			if ( ch == sc[i][j] ) {//筛选出ch所代表的窗口
				
				if ( i > x_max )
					x_max = i;
				
				if ( i < x_min )
					x_min = i;
				
				if ( j > y_max )
					y_max = j;
				
				if ( j < y_min )
					y_min = j;
				
				cnt++;
			}
	
	//一下都是剪枝
	if ( !cnt ) return FALSE;//该窗口不存在
	//被覆盖的边长小于题目要求的3
	if ( x_max - x_min < 2 ) return FALSE;
	if ( y_max - y_min < 2 ) return FALSE;
	//如果窗口是完整的则字母总数应该是( x_max + y_max - x_min - y_min ) × 2个
	if ( cnt != ( ( x_max + y_max - x_min - y_min ) << 1 ) ) return FALSE;
			
	//最后一种剪枝就是如果窗口是完整的,但是内部有更小的窗口覆盖它,所以
	//检查一下内部有没其他大写字母即可
	for ( i = x_min + 1; i < x_max; i++ )
		for ( j = y_min + 1; j < y_max; j++ )
			if ( isupper( sc[i][j] ) )
				return FALSE;
					
	return TRUE;//是顶端窗口
}

int
main() {
	
	int		n, m;
	char	ch;
	int		i, j;
	
	while ( scanf("%d%d", &n, &m), n) {
		
		for ( i = 1; i <= n; i++ ) scanf("%s", sc[i] + 1);
		for ( ch = 'A'; ch <= 'Z'; ch++ )
			if ( isTop( ch, n, m ) )
				putchar(ch);
		putchar('\n');
	}
	
	return 0;
}

无注释代码:

#include <stdio.h>
#include <ctype.h>

#define	TRUE	1
#define	FALSE	0

#define	INF		101

#define	MAXSCSIZE		102

typedef	int		BOOL;

char	 sc[MAXSCSIZE][MAXSCSIZE];

BOOL
isTop( char ch, int n, int m ) {
	
	int		i, j;
	
	int		x_max, x_min;
	int		y_max, y_min;
	
	int		cnt;
	
	x_max = 0;
	y_max = 0;
	
	x_min = INF;
	y_min = INF;
	
	cnt = 0;
	
	for ( i = 1; i <= n; i++ )
		for ( j = 1; j <= m; j++ )
			if ( ch == sc[i][j] ) {
				
				if ( i > x_max )
					x_max = i;
				
				if ( i < x_min )
					x_min = i;
				
				if ( j > y_max )
					y_max = j;
				
				if ( j < y_min )
					y_min = j;
				
				cnt++;
			}
			
	if ( !cnt ) return FALSE;
	if ( x_max - x_min < 2 ) return FALSE;
	if ( y_max - y_min < 2 ) return FALSE;
	if ( cnt != ( ( x_max + y_max - x_min - y_min ) << 1 ) ) return FALSE;
			
	for ( i = x_min + 1; i < x_max; i++ )
		for ( j = y_min + 1; j < y_max; j++ )
			if ( isupper( sc[i][j] ) )
				return FALSE;
					
	return TRUE;
}

int
main() {
	
	int		n, m;
	char	ch;
	int		i, j;
	
	while ( scanf("%d%d", &n, &m), n) {
		
		for ( i = 1; i <= n; i++ ) scanf("%s", sc[i] + 1);
		for ( ch = 'A'; ch <= 'Z'; ch++ )
			if ( isTop( ch, n, m ) )
				putchar(ch);
		putchar('\n');
	}
	
	return 0;
}
单词解释:

alphabet:n, 字母表

guarantee:vt/n, 保证

priority:n, 优先,优先权

assign:vt, 分配,赋值

interact:vt, 互动,相互作用

overlap:n, 重叠; vt, 与...重叠

frame:n, 框架

rectangular:adj, 矩形的

capital:adj, 大写的

monitor:n, 监控,监视器

graphical:adj, 图形的,图解的

conservative:adj, 保守的; n, 保守派

incredible:adj, 难以置信的,惊人的

Sheryl:人名,夏尔

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值