有n行n列的小黑点,还有m条线段连接其中的一些小黑点。统计这些线段连成了多少个正方形(每种边长分别统计)
行从上到下的编号为1~n,列从左到右编号为1~n,边用H i j和V i j表示,分别代表边(i,j)_(i,j+1)和(i,j)_(i+1,j),如图下图所示最左边的线段用V 1 1表示。图中有包含两个边长为1的正方形和一个边长为2的正方形。
输入样例:
4
16
H 1 1
H 1 3
H 2 1
H 2 2
H 2 3
H 3 2
H 4 2
H 4 3
V 1 1
V 1 2
V 1 4
V 2 2
V 2 3
V 2 4
V 3 2
V 3 4
————————
2
3
H 1 1
H 2 1
V 1 1
输出样例:
2个边长为1的正方形
1个边长为2的正方形
————————————
不存在正方形
分析问题:
这道题首先问题并不复杂,主要是如何设计代码,怎么用代码的形式去判断一个正方形是否存在。
1.对输入数据:
①H i j对应的是(i,j)这个点往右单位为1的一条边。
②V i j对应的是(i,j)这个点往下单位为1的一条边。
2.代码设计:
①分别用两个数组标志H和V所代表的边是否存在,有边则为1.
②用一个for循环来枚举所有1~n-1的所有边长进行判断。
③遍历每一个点,用这个点作为一个正方形的左上顶点,然后判断四条边是否存在,即是否全为1;
③当边长大于1时,可以用一个循环来判断以1为单位长度的一部分边长是否存在
代码:
#include<iostream>
#include<string.h>
using namespace std;
const int N = 10;
int H[N][N], V[N][N];
int n, m;
int square(int t)
{
int num = 0, flag = 0;
//遍历每一个点
for (int i = 1; i <= n -t ; i++)
{
for (int j = 1; j <= n - t; j++)
{
for (int k = 0; k < t; k++)//不同边长正方形的判断
{
if (H[i][j + k] && H[i + t][j + k] && V[i + k][j] && V[i + k][j + t])//判断是否为正方形
flag = 1;
else
{
flag = 0;
break;
}
}
if (flag)
num++;//正方形个数
}
}
return num;
}
int main()
{
memset(H, 0, sizeof(H));
memset(V, 0, sizeof(H));
cin >> n >> m;
while (m--)
{
char s;
int x, y;
cin >> s >> x >> y;
if (s == 'H')//标志存在的边
H[x][y] = 1;
else
V[x][y] = 1;
}
int flag = 0;
for (int i = 1; i <= n; i++)//边长
{
int sum = square(i);//边长为i的数量
if (sum)
{
cout << sum << "个边长为" << i << "的正方形"<<endl;
flag = 1;
}
}
if (!flag)
{
cout << "不存在正方形" << endl;
}
return 0;
}