UVA 297 Quadtrees 四分树

题目:https://cn.vjudge.net/problem/UVA-297

这个题目非正常的二分树,是四分树,在做题前读清题意;

题意:大正方形可以划分出四个小正方形,最大正方形的边长为32像素,且每一次分成的小正方形按逆时针编号为1,2,3,4。这样的划分可以用四分树来表示,且可以用先序的方式输入。四分树的节点有三种表示方式,f: 所划分出来的四个小块全为黑 e:所划分出来的四个小块全为白 p:所划分出来的四个小块既有黑也有白。 输入两棵四分树,使两个树相加,规则看图。最后需要求得黑色块的个数。(注:每个像素是一个 小块,也就是说大的正方形一共有32*32=1024个像素块)

对于这个题目我举一个例子,

对于这样一个分块的长条:

 

 

要求进行两次操作,每一次操作可以涂黑若干个方块,问两次一共涂黑了多少个方块。

对于这个问题我们可以这样解,设一个全局变量,在涂黑前判断是否已经涂黑,若没有则涂黑,则涂黑给全局变量+1,则两次操作后的全局变量的结果就是最终的答案,这个操作就是边涂边统计的。

理解了上面的操作扩展到二维上来就是本题了。一个32*32的正方形,每一个小正方形都可以被涂黑,问两次一共涂了多少黑块。

#include <bits/stdc++.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
//#define  LOCAL
using namespace std;
const int maxn=1024+10;
const int len=32; ///每个正方形边长是32
char s[maxn];
int buf[len][len],cnt;
void draw(const char*s,int &p,int r,int c,int w)  ///r c代表画图的左上角坐标  w代表边长 
{
	char ch=s[p++];
	if(ch=='p')
	{
		draw(s,p,r,     c+w/2,w/2);
		draw(s,p,r,     c,w/2);
		draw(s,p,r+w/2, c,w/2);
		draw(s,p,r+w/2, c+w/2,w/2);
	}else if(ch=='f')
	{
		for(int i=r;i<r+w;i++)  ///这一块不好理解 需理解为什么是要<r+w  不直接是(r,c)这个点,因为这是一棵四分树
			for(int j=c;j<c+w;j++) ///从根节点开始是代表的整个大正方形,每下降一层所代表的正方形就会变成上一层的1/4
				if(buf[i][j]==0) {buf[i][j]=1;cnt++;}///既然代表大正方形,大正方形每条边都很会包含相应的最小的像素块数,所以这里要像二维数组那样,涉及到每一块
	}
}
int main()
{
	#ifdef LOCAL
    	freopen("in.txt","r",stdin);
    	//freopen("out.txt","w",stdout);
	#endif
	int t;cin>>t;
	while(t--)
	{
		memset(buf,0,sizeof buf);
		cnt=0;
		for(int i=0;i<2;i++)
		{
			scanf("%s",s);
			int p=0;
			draw(s,p,0,0,len);
		}
		printf("There are %d black pixels.\n",cnt);
	}
   	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值