您的位置:首页 > 其它

2008 北京区域赛 Ugly Windows

2012-06-13 14:13 218 查看
/*

题目:
找到所有在上面的窗口,窗口的大小最小高度和宽度均为3。

分析:
通过搜索找到左上右下的坐标,然后再判断边上或里面是否有其他的字母,另外
注意由于窗口的大小最小为3*3。由于最大为100*100,O(n^3)暴搜算法即可

注意细节:
6 10
..........
.AAAAAAAA.
.A.BBB..A.
.A.B.B..A.
.A.BBB..A.
.AAAAAAAA.

*/
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int X = 105;

char map[X][X];
int n,m;
int use[27];

struct point
{
int x,y;
};

bool bfs(int x,int y,char a)
{
use[a-'A'] = 1;
point lt,rb;
lt.x = x;
lt.y = y;

rb.x = x;
rb.y = y;
for(int i=x;i<n;i++)    //找到左上右下的坐标
for(int j=y;j<m;j++)
if(map[i][j]==a)
{
lt.x = min(lt.x,i);
lt.y = min(lt.y,j);
rb.x = max(rb.x,i);
rb.y = max(rb.y,j);
}
if(rb.x-lt.x<2||rb.y-lt.y<2)    //大小不符
return false;

for(int i=lt.x;i<=rb.x;i++) //判断边上是否全为该字母
if(map[i][y]!=a||map[i][rb.y]!=a)
return false;
for(int i=lt.y;i<=rb.y;i++)
if(map[lt.x][i]!=a||map[rb.x][i]!=a)
return false;

for(int i=lt.x+1;i<rb.x;i++)    //判断里面是否有其他的窗口
for(int j=lt.y+1;j<rb.y;j++)
if(map[i][j]!='.')
return false;
return true;
}

int main()
{
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
while(scanf("%d%d",&n,&m),n||m)
{
if(n<3||m<3)
{
printf("1\n");
continue;
}
for(int i=0;i<n;i++)
scanf("%s",map[i]);
memset(use,0,sizeof(use));
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(map[i][j]!='.'&&!use[map[i][j]-'A'])
if(bfs(i,j,map[i][j]))
use[map[i][j]-'A'] = 2;
for(int i=0;i<26;i++)
if(use[i]==2)
printf("%c",(char)('A'+i));
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: