习题4-2:正方形 UVa201
不会做图片,见谅
环境为C语言
代码如下:
#include<stdio.h>
#include<string.h>
void main()
{
int H[10][9],V[10][9], res[10];//H储存行,V存列;res存结果,如res[3]为1时表示边长为3的正方形有1个
int npoint,len,tag=1;
memset(H,0,sizeof(H)),memset(V,0,sizeof(V)),memset(res,0,sizeof(res));
scanf("%d",&npoint); //npoint变量为一行或列上点的数目
len=npoint-1; //len变量存放正方形边长,初始化设为边长最长,由两点间只有一条线段可知最大边长为点数减一
H[1][1]=H[1][3]=H[2][1]=H[2][2]=H[2][3]=H[3][2]=H[4][2]=H[4][3]=1;//为1表示存在从该下标出发的线段
V[1][1]=V[2][1]=V[2][2]=V[2][3]=V[3][2]=V[4][1]=V[4][2]=V[4][3]=1; //将行和列输入,这两步可以随便自己设,这些点是根据书上图片取的
while(len>0) //主体;当边长为0时不满足正方形,退出循环
{
for(int i=1;i+len<=npoint;++i)
{for (int j=1;j+len<=npoint;++j) //(i,j)可看做正方形的左上角点(起点),需满足不超出边界
{for(int n=0;n<len;++n) //在确定好正方形边长和起点后,通过循环自增n可走完该正方形的全部边
if(H[i][j+n]==0||H[i+len][j+n]==0||V[j][i+n]==0||V[j+len][i+n]==0) {tag=0;break;}//关键步骤,判断正方形相对的两条行和列
if(tag==1) res[len]++; //在上步中一次判断了4段边,如果是边长为1的正方形,那一次就完成判断;只要有一条边为0,标志位tag置0
tag=1;}} //完成1个起点的正方形判定后重置标志位,准备下一次判定;
len--;} //完成1种边长的正方形判定后,调整边长准备下一轮判定;
for(int i=1;i<npoint;i++)
printf("[%d]:%d ",i,res[i]); //打印结果
}
#总结:我在读题时看了好久才明白行和列是怎么分的,懂了后面就好做了。主体部分为4层循环,过多嵌套总感觉不太好。最内层的那个if判定根据调试自己画一下就很好理解了。