这题我还是选择了看题解的思路
想不到想不到,是我菜了
其实题目的提示的老明显了,H与V一个横一个竖,说明对一个点来说,要分横竖把其可连的边储存,
(注意存的时候要保持V和H 行与列保持一致!!!)
然后又是求有多少个正方形,来一波暴力枚举(反正最多64个点)
存的时候存的是其每个点最多可以有多长的边,对于该点,一右一下,分别用 hc与 vc 储存
有人就问,这不就才两条边吗,一个正方形有四条边啊,这就是技术的一步,我们已经搞定了正方形的上 hc[i][j] 和左 vc[i][j] ,接下来就找规律, 发现下,就是 hc[i+z][j] ,而右,则是 vc[i][j+z] ,(z为此时确定的正方形边长) 好像这样就搞定了
啊,是我菜了…
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 16;
char s[4];
int hc[MAXN][MAXN],vc[MAXN][MAXN],H[MAXN][MAXN],square[MAXN],
V[MAXN][MAXN];
int main()
{
int m;
for(int t = 1;scanf("%d",&m)==1; t++)
{
if(t > 1) printf("\n**********************************\n\n");//小心输出
int n,a,b;
scanf("%d",&n);
memset(H,0,sizeof(H));memset(V,0,sizeof(V));
memset(hc,0,sizeof(hc));memset(vc,0,sizeof(vc));
memset(square,0,sizeof(square));
//initialize
for (int i = 0; i < n; i++)
{
scanf("%s%d%d",s,&a,&b);
if(s[0]=='H') H[a][b]++;
else V[b][a]++;//存下横和竖
}//看清!!!v[b][a]保证 V与H 都是先行后列储存
for (int i = m; i >= 1; i--)//从后往前
for (int j = m; j>=1; j--)
{
if(H[i][j]) hc[i][j] = hc[i][j+1]+1;
if(V[i][j]) vc[i][j] = vc[i+1][j]+1;
}//存下其该点最长的延伸
//一波查找猛如虎
for (int i = 1; i <= m; i++)
for (int j = 1; j <= m; j++)
{
int maxn = min(hc[i][j],vc[i][j]);
for (int z = 1;z <= maxn; z++)
{
if(vc[i][j+z] >= z && hc[i+z][j] >= z)
{
square[z]++;
} //自己画个图就知道啦为什么是 j+z 与 i+z
}
}
int ok = 0;
printf("Problem #%d\n\n",t);//小心输出
for (int i = 1; i <= m; i++)
{
if(square[i])
{
ok = 1;
printf("%d square (s) of size %d\n",square[i],i);
}
}
if(!ok) printf("No completed squares can be found.\n");
}
return 0;
}