图形转换为二维数列,顶点为1,最小边的一半为一个线段长度单位,线段为1,未连接为0
对每个顶点作为左上顶点,以边长为2~x(x为顶点右边剩余长度,步长为2)的正方形框去取数列,求出各边上数的积
满足框上各边上点的乘积不为0,则框的四个顶点是封闭的正方形
#include<iostream>
#include<stdlib.h>
using namespace std;
const int side_min=2; //最小边长为2,也作为循环用的步长
const int side_max=16; //最大边长为16
const int img[17][17]={ //将原图转换为数图,以下计算以此图进行
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1},
{1,0,0,0,1,0,1,1,1,1,1,0,1,0,0,0,1},
{1,0,0,0,1,0,1,0,1,0,1,0,1,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,1,0,1,0,1,0,1,0,1,0,0,0,1},
{1,0,0,0,1,0,1,1,1,1,1,0,1,0,0,0,1},
{1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1},
{1,0,0,0,1,0,1,1,1,1,1,0,1,0,0,0,1},
{1,0,0,0,1,0,1,0,1,0,1,0,1,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,1,0,1,0,1,0,1,0,1,0,0,0,1},
{1,0,0,0,1,0,1,1,1,1,1,0,1,0,0,0,1},
{1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}};
struct position{int x;int y;} //位置的结构
vertex[9][9]; //顶点
void getvertex(){ //获得各顶点的位置
for(int i=0;i<9;i=i+1){
for(int j=0;j<9;j=j+1){
vertex[i][j].x=side_min*i;
vertex[i][j].y=side_min*j;
} }
}
int main()
{
getvertex();
int count=0;
int x,y,side_valid;
for(int r=0;r<9;r=r+1){ //定行
for(int c=0;c<9;c=c+1){ //定列
x=vertex[r][c].x;y=vertex[r][c].y;//定点
side_valid=(x<y)?side_max-y:side_max-x;
for(int side=side_min;side<=side_valid;side=side+2){//定框
int pro_t=1,pro_b=1,pro_l=1,pro_r=1;//框上各边上点的积
for(int i=0;i<=side;i=i+1){ //框上竖边上的点
pro_l=pro_l*img[x][y+i];
pro_r=pro_r*img[x+side][y+i];
}
for(int j=0;j<=side;j=j+1){ //框上横边上的点
pro_t=pro_t*img[x+j][y];
pro_b=pro_b*img[x+j][y+side];
}
if(pro_t!=0 && pro_b!=0 && pro_l!=0 && pro_r!=0){
count=count+1;}
}
}
}
cout<<"有"<<count<<"个正方形\n";
system("pause");return 0;
}