思路就是将每条边的所连续的长度给保存起来,然后找出所能构成正方形的规律。。接着遍历数组固定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; }