例题6-11 UVa297-Quadtrees(不同于紫书的解法,基于指针的树实现)

第一次遇到四叉树的题目。紫书上相当于创建了32×32的二维数组来模拟整个大方块。而我的思路是:仿照建二叉树的方法建四叉树,只是多了两个子节点而已。分别用-1,0,1来表示当前节点的颜色,以便于合并以及计数。合并的细节我写到了注释里。计数时,将根结点(即最外层的大方块)看做拥有32×32=1024个像素点,那么第二层中,每个结点拥有1024/(2^2)个结点,以此类推。

题目链接:UVa 297

AC代码:

#include <iostream>
#include <cmath>
#include <queue>
using namespace std;

struct Node {
	int data; //data三个取值-1,0,1.分别代表白、灰、黑
	Node* first, * second, * third, * fourth;
	Node() :first(NULL), second(NULL), third(NULL), fourth(NULL) {}
}*r, * root1, * root2;
queue<char> q;

void read_input(queue<char>& v) {
	string s;
	cin >> s;
	while (!v.empty())
		v.pop();
	for (int i = 0; i < s.length(); i++)
		v.push(s[i]);
}
void build(Node*& node, queue<char>& v) {
	node = new Node();
	if (v.front() == 'p') {
		v.pop();
		node->data = 0;
		build(node->first, v);
		build(node->second, v);
		build(node->third, v);
		build(node->fourth, v);
	}
	else if (v.front() == 'f') {
		v.pop();
		node->data = 1;
	}
	else if (v.front() == 'e') {
		v.pop();
		node->data = -1;
	}
}
void remove(Node* u) {
	if (u == NULL) return;
	remove(u->first);
	remove(u->second);
	remove(u->third);
	remove(u->fourth);
	delete u;
}
void add(Node* r1, Node* r2, Node*& root) {
	root = new Node();
	if (r1->data == 1 || r2->data == 1)  //其中一个是黑结点,合并后也是黑结点
		root->data = 1;
	else if (r1->data == -1 && r2->data == -1)  //都是白结点,合并后才是白结点
		root->data = -1;
	else if (r1->data == 0 && r2->data == -1)
		root = r1;
	else if (r1->data == -1 && r2->data == 0)  //一灰一白,合并后与灰相同
		root = r2;
	else {  //都是灰结点,递归合并
		root->data = 0;
		add(r1->first, r2->first, root->first);
		add(r1->second, r2->second, root->second);
		add(r1->third, r2->third, root->third);
		add(r1->fourth, r2->fourth, root->fourth);
	}
}
int count(Node* node, int i) { //自根向下,每层黑结点代表的像素块依次减少
	int n = 0;
	if (node->data == 1)
		n = pow(2, i);
	else if (node->data == 0) {
		n += count(node->first, i - 2);
		n += count(node->second, i - 2);
		n += count(node->third, i - 2);
		n += count(node->fourth, i - 2);
	}
	return n;
}
int main() {
	int T;
	cin >> T;
	while (T--) {
		read_input(q), build(root1, q);
		read_input(q), build(root2, q);
		add(root1, root2, r);
		cout << "There are " << count(r, 10) << " black pixels." << endl;
		remove(r);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值