思路就是将每条边的所连续的长度给保存起来,然后找出所能构成正方形的规律。。接着遍历数组固定v来找对应的h看是否能满足构成正方形的条件。。
对于这个图来说,假设我们固定V13来看,当V13 V23 H31 H41 都满足>=1时就可构成边长为1的正方形。
当V13 V33 H22 H42都满足>=2时也可构成2的正方形。当V13 V43 H13 H43都满足>=3时也可构成3的正方形。仔细观察每个位置的ij 的变化,那么这样我们很容易找出能够正方形的规律来。
详细的规律可以看代码。。一次AC还是蛮开心的~毕竟对于我来说也不水。。
#include<stdio.h>
#include<string.h>
int h[15][15];
int v[15][15];
int sq[15];
int main ()
{
int n,m,kase=0;
while (scanf("%d%d",&n,&m)==2)
{
char ch;
int x,y,i,j,k;
memset(sq,0,sizeof(sq));
memset(h,0,sizeof(h));
memset(v,0,sizeof(v));
while(m--)
{
while((ch=getchar())=='\n');
scanf("%d%d",&x,&y);
if(ch=='H')
h[x][y]=h[x][y-1]+1; //求出该位置已经有多少条连续的长度为 1的边
else v[x][y]=v[x][y-1]+1;
}
//遍历整个棋盘
for(i=1;i<=n;i++)
{
for(j=1;j<n;j++)
{
int a=j,b=i;
for(k=1;k<=v[i][j];k++) //对于这条边来说他所可能构成的最大的正方形的边长为这个数
{
if(v[i][j]>=k&&v[i+k][j]>=k&&h[a][b]>=k&&h[j+1][b]>=k) //对于这些数来说只需要大于等于k就可以构成以k为边长的数组
sq[k]++; //表示边长为k的正方形的个数
a--;
b++;
}
}
}
if(kase==0)
printf("Problem #%d\n",++kase);
else
printf("\n**********************************\n\nProblem #%d\n",++kase);
printf("\n");
int flag=0;
for(i=1;i<=9;i++)
{
if(sq[i])
{
printf("%d square (s) of size %d\n",sq[i],i);
flag=1;
}
}
if(!flag) printf("No completed squares can be found.\n");
}
return 0;
}