习题4_2 uva201 正方形

这题我还是选择了看题解的思路
想不到想不到,是我菜了
其实题目的提示的老明显了,H与V一个横一个竖,说明对一个点来说,要分横竖把其可连的边储存,
(注意存的时候要保持V和H 行与列保持一致!!!)
然后又是求有多少个正方形,来一波暴力枚举(反正最多64个点)
存的时候存的是其每个点最多可以有多长的边,对于该点,一右一下,分别用 hc与 vc 储存
有人就问,这不就才两条边吗,一个正方形有四条边啊,这就是技术的一步,我们已经搞定了正方形的上 hc[i][j] 和左 vc[i][j] ,接下来就找规律, 发现下,就是 hc[i+z][j] ,而右,则是 vc[i][j+z] ,(z为此时确定的正方形边长) 好像这样就搞定了
啊,是我菜了…

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 16;
char s[4];
int hc[MAXN][MAXN],vc[MAXN][MAXN],H[MAXN][MAXN],square[MAXN], 
V[MAXN][MAXN];
int main()
{
	int m;
	for(int t = 1;scanf("%d",&m)==1; t++)
	{
		if(t > 1) printf("\n**********************************\n\n");//小心输出 
		int n,a,b;
		scanf("%d",&n);
		memset(H,0,sizeof(H));memset(V,0,sizeof(V));
		memset(hc,0,sizeof(hc));memset(vc,0,sizeof(vc));
		memset(square,0,sizeof(square));
		//initialize 
		for (int i = 0; i < n; i++)
		{
			scanf("%s%d%d",s,&a,&b);
			if(s[0]=='H') H[a][b]++;
			else V[b][a]++;//存下横和竖 
		}//看清!!!v[b][a]保证 V与H 都是先行后列储存 
		for (int i = m; i >= 1; i--)//从后往前 
		  for (int j = m; j>=1; j--)
		  {
		  	if(H[i][j]) hc[i][j] = hc[i][j+1]+1;
		  	if(V[i][j]) vc[i][j] = vc[i+1][j]+1;
		  }//存下其该点最长的延伸 
		//一波查找猛如虎 
		for (int i = 1; i <= m; i++)
		 for (int j = 1; j <= m; j++)
		 {
		 	int maxn = min(hc[i][j],vc[i][j]);
		 	for (int z = 1;z <= maxn; z++)
		 	{
		 		if(vc[i][j+z] >= z && hc[i+z][j] >= z)
		 		{
		 			square[z]++;
		 		} //自己画个图就知道啦为什么是 j+z 与 i+z 
		 	}
		 } 
	   int ok = 0;
	   printf("Problem #%d\n\n",t);//小心输出
	   for (int i = 1; i <= m; i++)
	   {
	   		if(square[i])
	   		{
	   			ok = 1;
	   			printf("%d square (s) of size %d\n",square[i],i);
	   		}
	   }
	   if(!ok) printf("No completed squares can be found.\n");
	}
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值