UVa 201 Squares(正方形)


题意:

有n行n列(2<=n<=9)的小黑点,还有m条线段连接其中的一些黑点。统计这些线段连成了多少正方形。(每种边长分别统计)。

行从上到下编号为1~n,列从左到右编号为1~n。边用H i j和V i j表示,分别代表(i,j)-(i,j+1)和(i,j)-(i+1,j)。


思路:

读入的时候,先对每个点是否存在先左或向下的边做标记。然后统计从这点开始向左和向下的最大边长。如果要判断是否存在以(i,j)为左上顶点的边长为len的正方形,只需要判断以(i,j)为起点向左和向下的最大边长,以(i+len,j)为起点的向左的最大边长,以(i,j+len)为起点的向下的最大边长是否都满足>=len。

对于n*n个点最大的正方形边长是n-1。

#include <stdio.h>
#include <string.h>
#define maxn 11
struct POINT {
	int R;//表示该点向右的最大边长
	int C;//表示该点向下的最大边长
}a[maxn][maxn];
int n, m, r, c, ans[maxn], cases=0, count, first=1;
char s[2];
void clear()
{
	for (int i = 0;i <= maxn;i++)
		for (int j = 0;j <= maxn;j++)
		{
			a[i][j].R = 0;
			a[i][j].C = 0;
		}
}
int main()
{
#ifdef LOCAL
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif
	while (~scanf("%d%d", &n,&m))
	{
		memset(ans, 0, sizeof(ans));
		clear();
		for (int i = 1;i <= m;i++)
		{
			scanf("%s%d%d", s, &r, &c);
			if (s[0] == 'H') a[r][c].R= 1;
			else a[c][r].C = 1;//注意下标的变化
		}
		for (int i = 1;i <= n;i++)
		{
			for (int j = 1;j <= n;j++)
			{
				if (a[i][j].R)//如果该点先左有边
				{
					for (int k = j + 1;k <= n;k++)//从该点一直向左统计最大边长
						if (a[i][k].R) a[i][j].R++;
						else break;//遇到连接中断退出
				}
				if (a[i][j].C)
				{
					for (int k = i + 1;k <= n;k++)
						if (a[k][j].C) a[i][j].C++;
						else break;
				}
			}
		}
		/*
		for (int i = 1;i <= n;i++)
		{
			for (int j = 1;j <= n;j++)
				printf("(%d,%d) ", a[i][j].R, a[i][j].C);
			printf("\n");
		}
		*/
		for (int len = 1;len < n;len++)//最大可能边长是n-1
		{
			for (int i = 1;i <= n - len;i++)
			{
				for (int j = 1;j <= n - len;j++)
					if (a[i][j].R >= len&&a[i][j].C >= len&&a[i + len][j].R >= len&&a[i][j + len].C >= len)
						ans[len]++;//ans[len]表示以len为边长的正方形数量
			}
		}
		if (first) first = 0;
		else printf("\n**********************************\n\n");
		printf("Problem #%d\n\n", ++cases);
		count = 0;
		for (int i = 1;i < n;i++)
		{
			if (ans[i])
			{
				count++;
				printf("%d square (s) of size %d\n", ans[i], i);
			}
		}
		if (!count) //不存在正方形
			printf("No completed squares can be found.\n");
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值