用两个数组存水平线和竖直线,然后先枚举正方形的边长,然后对于每个边长枚举方格内的所有顶点,对于每个顶点,向右枚举处于同一水平边和对边的点,向下枚举处于同一竖直边和对边的点,如果枚举过程中任何一个顶点未在对应数组中有记录,说明该点不存在连线,自然不可组成正方形,否则遍历能正常结束,说明所有点都有连线,计数加1,输出当前边长的正方形数
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
int v[11][11],h[11][11]; //分别存竖直线和水平线
int m,n,k=0;
while(k++,cin>>n>>m)
{
bool noans=true; //标记是否有正方形
memset(v,0,sizeof(v));
memset(h,0,sizeof(h));
char mode;
int a,b;
for(int i=0;i<m;i++)
{
cin>>mode>>a>>b;
if(mode=='H')
h[a][b]++; //将线段信息存入数组
else
v[b][a]++; //这里按照紫书的描述应该是v[a][b],但是原题不是这样。。。坑
}
if(k!=1)
cout<<endl<<"**********************************"<<endl<<endl;
cout<<"Problem #"<<k<<endl<<endl;
for(int s=1;s<n;s++) //枚举边长
{
int cont=0;
for(int i=1;i<=n-s;i++) //枚举左上顶点
for(int j=1;j<=n-s;j++)
{
bool mark=true; //标记当前顶点是否可能有当前边长的正方形
for(int x=i,y=j;mark&&x<i+s;x++)
if(!v[x][y]||!v[x][y+s]) //任何一点无连线则不可能组成正方形
mark=false;
for(int x=i,y=j;mark&&y<j+s;y++)
if(!h[x][y]||!h[x+s][y])
mark=false;
if(mark) //可组成正方形则当前边长正方形数量累加
cont++;
}
if(cont)
{
cout<<cont<<" square (s) of size "<<s<<endl;
noans=false;
}
}
if(noans) //无结果
cout<<"No completed squares can be found."<<endl;
}
return 0;
}