问题 J: Image Processing Project
时间限制: 1 Sec 内存限制: 128 MB
题目编号:10732
题目描述
You want to be recruited in Cafebazaar, a leading IT company in Iran, as part of an image processing project for detecting celestial bodies. To prove yourself, you should do a pilot project in a matter of hours for the project manager.
The project manager has put some paper sheets on a rectangular table whose color is white. All paper sheets are square and have the same size. Moreover, all paper sheets are white but their boundaries are black. Each side of all paper sheets is parallel to an edge of the table. You must write an image processing program to count the number of paper sheets by receiving a picture of the table taken from above.
输入
The first line of the input contains two positive integers r and c (3 ⩽ r, c ⩽ 200) denoting the number of rows and columns of the given picture, respectively. Precisely, the picture is an r × c table of pixels. The next r lines, each contains exactly c characters. Each character is +, -, or . representing a pixel of the picture. A dash pixel illustrates one unit of a horizontal side of a paper sheets. A plus pixel illustrates either one unit of a vertical side of a paper sheet or a corner of a paper sheet.
A dot pixel is a white pixel.
You can assume that in each row there exists at most one horizontal side. Similarly, in each column, there exists at most one vertical side. It is guaranteed that at least two corners of each paper sheet are visible. A corner is visible when along with the pixel corresponding to the corner, at least one immediate pixel from each of its incident edges is also present in the input. Moreover, It is guaranteed that there is at least a dash pixel in the input.
输出
Print the number of paper sheets in the output.
样例输入
10 13
+---+........
+...+........
+...+...+---+
+...+-+.+...+
+---+.+.+...+
..+..+--+...+
..+..+..+---+
..+--+...+...
.....+...+...
.....+---+...
样例输出
4
题目分析
每个矩形大小相等,矩形间可能存在遮挡但保证露出至少两个角,求此类矩形的个数
思路
矩形间相互遮挡,但一定存在没有被遮挡的矩形,因此可以先找到最大的合法矩形,此矩形必然是没有被遮挡的那个,然后对图像进行搜索与匹配,将所有搜过的点看做任意字符处理,如果一次遍历之后没有搜到新增的矩形,则可以停止遍历。
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=205;
char a[N][N];
int n,m;
bool vis[N][N],v2[N][N];
int C=1,L=1;
void findsqr()
{
//函数功能:找到最大矩形并记录最大矩形横向纵向长度
//memset(vis,0,sizeof vis);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(a[i][j]=='+')
{
int c,l;
for(int k=j+1;k<m;k++)//找到此点为左上角的最大矩形
if(a[i][k]=='+')
{
c=k-j;
break;
}
bool flag=true;
for(int k=i+1;k<n&&flag;k++)
for(int p=0;p<c;p++)
{
if((p==0||p==c)&&(a[k][p+j]!='+')||((p>0&&p<c)&&a[k][p+j]!='.'))
{
l=k-i;
flag=false;
break;
}
}
if((c+1)*(l+1)>(C+1)*(L+1))//判断矩形合法性
{
bool flag=true;
for(int ii=0;ii<=l&&flag;ii++)
for(int jj=0;jj<=c&&flag;jj++)
{
if(a[i+ii][j+jj]!=((jj==0||jj==c)?'+':((ii==0||ii==l)?'-':'.')))
{
flag=false;
break;
}
}
if(flag==false) continue;
C=c;
L=l;
}
}
}
int countsqr(int t)
{
//函数功能:查找矩形个数
int c=C,l=L;
int temp=t;
for(int i=0;i<=n-l;i++)
for(int j=0;j<=m-c;j++)
if(vis[i][j]||a[i][j]=='+')
{
int cnt=0;
if(v2[i][j]) continue;//v2存储已经找到的矩形的左上角坐标,若v2已经存储过则跳过
bool flag=true;
for(int ii=0;ii<=l&&flag;ii++)//判断合法性
for(int jj=0;jj<=c&&flag;jj++)
{
if(!vis[i+ii][j+jj]&&((a[i+ii][j+jj])!=((jj==0||jj==c)?'+':((ii==0||ii==l)?'-':'.'))))
{
flag=false;
break;
}
if(!vis[i+ii][j+jj]&&(ii==0||ii==l)&&(jj==0||jj==c))
cnt++;
}
if(cnt<2) continue;
if(flag)//标记找到的矩形
{
t++;
v2[i][j]=true;
for(int ii=0;ii<=l&&flag;ii++)
for(int jj=0;jj<=c&&flag;jj++)
{
vis[i+ii][j+jj]=true;
}
}
}
return temp==t?t:countsqr(t);//如果t值发生改变则重新调用本函数再一次搜索,否则直接返回
}
int main()
{
//bool f=true;
cin>>n>>m;
for(int i=0;i<n;i++)
{
cin>>a[i];
for(int j=0;j<m;j++)
//if(a[i][j]=='-') f=false;
}
findsqr();
cout<<countsqr(0);
return 0;
}