习题4-2 正方形

题目:
在这里插入图片描述
大意就是给出n和m,构造N^2点数的正方形并输入m条指令:
H i j 代表横向连接坐标为 (i, j)和坐标为 (i, j + 1)的两点;
V i j 代表纵向连接坐标为 (i, j)和坐标为 (i + 1, j)的两点。
问最终能连成不同边长的正方形各多少个。

解析:
对于不同的指令,我想到用两个数组V[n][n]和H[n][n]来保留操作,对于每个点的坐标,分别统计以它为起点的不同边长正方形的个数,最后加和即可。假设最初两个数组全为0,联通则置1,那么判断应该为:

if (!H[i][j + k] || !H[i + len][j + k]) {
	flag = 0;break;
}
if (!V[i + k][j] || !V[i + k][j + len]) {
	flag = 0;break;
}

可是真到了编程却不能越过逻辑的坎儿。看了一下网上其他人的代码,才发现是自己的逻辑出错了。正确的想法应该是:对于不同边长的正方形个数进行依次统计(这是最外层循环,这样才能有i+len<=n的限制条件),一个正方形如果完整,那么它的每条边都存在,因此在最内层循环遍历它的每条边,只要有一条边不存在即可退出,否则计数。

代码:

//习题4-2 正方形
#include<iostream>
#include<Windows.h>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<ctype.h>
#include<cmath>
#define MAXN 10
using namespace std;
int H[MAXN][MAXN], V[MAXN][MAXN];
int main()
{
	int i, j, k, n, m, x, y, len;
	int flag = 1;
	int cnt = 0, sum = 0;
	char ch;
	cin >> n >> m;
	memset(V, 0, sizeof(V));
	memset(H, 0, sizeof(H));
	while(m--)
	{
		getchar();
		ch = getchar();
		scanf("%d%d", &x, &y);
		if (ch == 'V') V[x][y] = 1;
		else H[x][y] = 1;
	}
	for (len = 1;len <= n;len++)	//正方形的边长范围
	{
		cnt = 0;
		for (i = 1;i + len <= n;i++)
		{
			for (j = 1;j + len <= n;j++)
			{
				flag = 1;
				for (k = 0;k < len;k++)	//遍历每条边(个点),只要有不连通的就退出
				{
					if (!H[i][j + k] || !H[i + len][j + k]) {	//上与下、左与右坐标之间差的是一个边长
						flag = 0;break;
					}
					if (!V[i + k][j] || !V[i + k][j + len]) {
						flag = 0;break;
					}
				}
				cnt += flag;	//对于每种边长的个数
			}
		}
		sum += cnt;	//总个数
		if (cnt) printf("%d square (s) of size %d\n", cnt, len);
	}
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/cprimesplus/article/details/83817534