poj_3923 Ugly Windows

Ugly Windows

Time Limit: 1000MS

Memory Limit: 65536K

Total Submissions: 822

Accepted: 228

题目链接:http://poj.org/problem?id=3923

Description

Sheryl works for a softwarecompany in the country of Brada. Her job is to develop a Windows operatingsystem. People in Brada are incredibly conservative. They even never usegraphical monitors! So Sheryl's operating system has to run in text mode andwindows in that system are formed by characters. Sheryl decides that everywindow has an ID which is a capital English letter ('A' to 'Z'). Because everywindow had a unique ID, there can't be more than 26 windows at the same time.And as you know, all windows are rectangular.

On the screen of that ugly Windows system, a window's frame is formed by its IDletters. Fig-1 shows that there is only one window on the screen, and thatwindow's ID is 'A'. Windows may overlap. Fig-2 shows the situation that windowB is on the top of window A. And Fig-3 gives a more complicated overlapping. Ofcourse, if some parts of a window are covered by other windows, you can't seethose parts on the screen.


.........................


....AAAAAAAAAAAAA........


....A...........A........


....A...........A........


....A...........A........


....AAAAAAAAAAAAA........


.........................




Fig-1




.........................


....AAAAAAAAAAAAA........


....A...........A........


....A.......BBBBBBBBBB...


....A.......B........B...


....AAAAAAAAB........B...


............BBBBBBBBBB...


.........................




Fig-2




..........................


....AAAAAAAAAAAAA.........


....A...........A.........


....A.......BBBBBBBBBB....


....A.......B........BCCC.


....AAAAAAAAB........B..C.


.......C....BBBBBBBBBB..C.


.......CCCCCCCCCCCCCCCCCC.


..........................




Fig-3

 


If a window has no parts covered by other windows, we call it a “top window”(The frame is also considered as a part of a window). Usually, the top windowsare the windows that interact with user most frequently. Assigning top windowsmore CPU time and higher priority will result in better user experiences. Giventhe screen presented as Figs above, can you tell Sheryl which windows are topwindows?

Input

The input contains severaltest cases.

Each test case begins with two integers, n and m (1 <= n, m <= 100),indicating that the screen has n lines, and each line consists of m characters.

The following n lines describe the whole screen you see. Each line contains mcharacters. For characters which are not on any window frame, we just replacethem with '.' .

The input ends with a line of two zeros.

It is guaranteed that:

1) There is at least one window on the screen.
2) Any window's frame is at least 3 characters wide and 3 characters high.
3) No part of any window is outside the screen.

Output

For each test case, output theIDs of all top windows in a line without blanks and in alphabet order.

Sample Input

9 26

..........................

....AAAAAAAAAAAAA.........

....A...........A.........

....A.......BBBBBBBBBB....

....A.......B........BCCC.

....AAAAAAAAB........B..C.

.......C....BBBBBBBBBB..C.

.......CCCCCCCCCCCCCCCCCC.

..........................

7 25

.........................

....DDDDDDDDDDDDD........

....D...........D........

....D...........D........

....D...........D..AAA...

....DDDDDDDDDDDDD..A.A...

...................AAA...

0 0

Sample Output

B

AD

Source

Beijing2008

 

题意:

         给你一张图,让你求顶端窗口,然后按照字母排序输出。给出顶端窗口的定义:

1、  每一张图至少有一个窗口

2、  每个窗口矩形大于等于3

3、  窗口不可能超出图的范围

解题思路:

         两个函数来决解:第一个函数判断该图中出现的不同字母,保存第一个字母的坐标,第二个函数遍历每个字母对应的矩形,判断是否是完整的矩形,我是遍历四条边,记录每个矩形的长度,要提出内嵌矩形的情况。

给出几组测试用例:

/*

8 25

.........................

....AAAAAAAAAAAAA........

....A...........A........

....A...BBBBB...A........

....A...B...B...A........

....A...BBBBB...A........

....A...........A........

....AAAAAAAAAAAAA........

 

6 6

AAA...

A.A...

AABBB.

..B.B.

..BBB.

......

 

6 6

AAA...

A.A...

AABBBB

..B..B

..B..B

..BBBB

6 6

AAA...

A.A...

BBBBBB

B....B

B....B

BBBBBB

 

6 6

AAA...

ABBBBB

AB...B

.B...B

.BBBBB

......

 

6 6

AAA...

ABBBBB

ABCCCB

.BC.CB

.BCCCB

.BBBBB



6 6

AAABBB

A.AB.B

AAABBB

CCCDDD

C.CD.D

CCCDDD

 

 

9 9

AAAAAAAAA

ABBBBBBBA

ABCCCCCBA

ABCDDDCBA

ABCD.DCBA

ABCDDDCBA

ABCCCCCBA

ABBBBBBBA

AAAAAAAAA

 

 

9 9

AABBCCDDD

AABBCCD.D

AABBCCDDD

EEEFFGGHH

E.EFF.G.H

EEEFFGGHH

IIIJKKKLL

I.I.K.K.L

IIIJKKKLL

*/

 

代码:

#include <iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define maxn 502
using namespace std;

struct trieTree
{//字典数组
	//矩阵对应第一个字符的坐标
    int x;
    int y;
	//矩阵对应的长和高
    int high;
    int length;
    int isVal;//记录是否是真正的结果
};
struct cmp{
	bool operator()(const char &a,const char &b){
		return a>b;
	}
};
int n,m;
char g[maxn][maxn];//存图
trieTree trie[maxn];//存图中每一个矩形对应的字母
int num;
int len;
priority_queue<char,vector<char>,cmp> q;//存储符合要求的字母

//判断起点x,y的点是不是答案
bool getResult(int t,int x,int y)
{
	int i;
	for(i=y;g[x][i]==g[x][y];i++)
	{
		trie[t].length++;
	}
	if(trie[t].length<=2)
		return false;
    for(i=x;g[i][y]==g[x][y];i++)
	{
		trie[t].high++;
	}
	if(trie[t].high<=2)
		return false;
	for(i=y;i<trie[t].length+y;i++)
	{
		if(g[x+trie[t].high-1][i]!=g[x][y])
			return false;
	}
	for(i=x;i<trie[t].high+x;i++)
	{
		if(g[i][y+trie[t].length-1]!=g[x][y])
			return false;
	}
	return true;


}

bool findChar(int x,int y)
{
    for(int i=0;i<num;i++)
    {
        //表示该字符在字典数组中
        if(g[x][y]==g[x][trie[i].y] && g[x][y]==g[trie[i].x][y])
        {
            return true;
        }
    }
	return false;
}

int main()
{
    int i,j;

    while(true)
    {
        scanf("%d%d",&n,&m);
		memset(trie,0,sizeof(trie));
	//	memset(g,'.',sizeof(g));
        if(!n && !m)
            break;
        getchar();
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                scanf("%c",&g[i][j]);
            }
            getchar();
        }
        num=0;
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                if(g[i][j]!='.')
                {
                    if(!findChar(i,j))
                    {//如果该字符不在字典数组中,那么加进去
                        trie[num].x=i;
                        trie[num].y=j;
						num++;
                    }
                }
            }
        }
		for(int t=0;t<num;t++)
		{
			//如果符合要求
			if(getResult(t,trie[t].x,trie[t].y))
			{
				trie[t].isVal=1;
				for(int i=0;i<num;i++)
				{//内嵌矩形
				    if(trie[i].isVal==1)
				    {
				        //表示第t个矩形在第i个矩形里面
				        if(trie[t].x>trie[i].x && trie[t].x<(trie[i].x+trie[i].high) && trie[t].y>trie[i].y && trie[t].y<(trie[i].y+trie[i].length))
                        {
                            trie[i].isVal=0;
                            continue;
                        }
				    }
				}
			}
		}
		for(int t=0;t<num;t++)
		{
		    if(trie[t].isVal==1)
		    {
		        q.push(g[trie[t].x][trie[t].y]);
		    }
		}
		while(!q.empty())
		{
            printf("%c",q.top());
            q.pop();
		}
		printf("\n");
    }
    return 0;
}


 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯的世界

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值