题目大意:
有一个矩形的图形框架,框架中有大写字母表示的矩形框架(因此矩形框架最都有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:人名,夏尔