算法竞赛入门经典 例题6-11

UVa297

Quadtrees

将利用四分树表示的灰度图片进行叠加,并统计结果中黑色像素的数量。

根据题目中给出的规律,如果原始图片中有黑色像素,那么结果就是黑色像素;如果原始图片中有白色像素,那么结果由另一张图片决定,因此如果已知原始图片中每个像素块中黑色像素的数量,就可以直接相加,也就避免了计算结果图片。

#include <iostream>
#include <array>
#include <memory>
#include <string>

using namespace std;

struct Node
{
	char color;
	int depth, black;
	array<shared_ptr<Node>, 4> children;
};

class Solution
{
public:
	Solution(const string &image1, const string &image2)
	{
		size_t index1 = 0, index2 = 0;
		construct(tree1, image1, index1, 0);
		construct(tree2, image2, index2, 0);
		AddImage(tree1, tree2);
	}
	int black = 0;
private:
	Node tree1, tree2;
	void construct(Node &root, const string &image, size_t &index, int depth)
	{
		root.color = image.at(index++);
		root.depth = depth;
		if (root.color == 'p') {
			for (size_t i = 0; i < root.children.size(); i++)
			{
				root.children[i] = make_shared<Node>();
				construct(*root.children[i], image, index, depth + 1);
				root.black += root.children[i]->black;
			}
		}
		else {
			int len = 1 << (5 - root.depth);
			root.black = root.color == 'f' ? len * len : 0;
		}
	}
	void AddImage(const Node &root1, const Node &root2)
	{
		int len = 1 << (5 - root1.depth);
		if (root1.color == 'f' || root2.color == 'f') {
			black += len * len;
		}
		else if (root1.color == 'e') {
			black += root2.black;
		}
		else if (root2.color == 'e') {
			black += root1.black;
		}
		else {
			for (size_t i = 0; i < root1.children.size(); i++)
			{
				AddImage(*root1.children[i], *root2.children[i]);
			}
		}
	}
};

int main()
{
	int N = 0;
	cin >> N;
	for (int i = 0; i < N; i++)
	{
		string image1, image2;
		cin >> image1 >> image2;
		Solution solution(image1, image2);
		cout << "There are " << solution.black << " black pixels." << endl;
	}
	return 0;
}
/*
3
ppeeefpffeefe
pefepeefe
peeef
peefe
peeef
peepefefe
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值