正方形(Squares,ACM/ICP Word Finals ,UVA)

有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;
}

猜你喜欢

转载自blog.csdn.net/weixin_41676901/article/details/81368004