297 - Quadtrees

来源:互联网 发布:微信抢红包排雷软件 编辑:程序博客网 时间:2024/05/15 20:10



 Quadtrees 

A quadtree is a representation format used to encode images. The fundamental idea behind the quadtree is that any image can be split into four quadrants. Each quadrant may again be split in four sub quadrants, etc. In the quadtree, the image is represented by a parent node, while the four quadrants are represented by four child nodes, in a predetermined order.

Of course, if the whole image is a single color, it can be represented by a quadtree consisting of a single node. In general, a quadrant needs only to be subdivided if it consists of pixels of different colors. As a result, the quadtree need not be of uniform depth.

A modern computer artist works with black-and-white images of tex2html_wrap_inline34 units, for a total of 1024 pixels per image. One of the operations he performs is adding two images together, to form a new image. In the resulting image a pixel is black if it was black in at least one of the component images, otherwise it is white.

This particular artist believes in what he calls the preferred fullness: for an image to be interesting (i.e. to sell for big bucks) the most important property is the number of filled (black) pixels in the image. So, before adding two images together, he would like to know how many pixels will be black in the resulting image. Your job is to write a program that, given the quadtree representation of two images, calculates the number of pixels that are black in the image, which is the result of adding the two images together.

In the figure, the first example is shown (from top to bottom) as image, quadtree, pre-order string (defined below) and number of pixels. The quadrant numbering is shown at the top of the figure.

Input Specification

The first line of input specifies the number of test cases (N) your program has to process.

The input for each test case is two strings, each string on its own line. The string is the pre-order representation of a quadtree, in which the letter 'p' indicates a parent node, the letter 'f' (full) a black quadrant and the letter 'e' (empty) a white quadrant. It is guaranteed that each string represents a valid quadtree, while the depth of the tree is not more than 5 (because each pixel has only one color).

Output Specification

For each test case, print on one line the text 'There are X black pixels.', whereX is the number of black pixels in the resulting image.

Example Input

3ppeeefpffeefepefepeefepeeefpeefepeeefpeepefefe

Example Output

There are 640 black pixels.There are 512 black pixels.There are 384 black pixels.

分析:各层像素点是如何计算的?根据题意,一张完整的图有1024个像素点,那么第一层的每个结点有1024/1=1024个像素点,第二层每个结点有1024/4=256个像素点(因为第二层有4个结点),第三层每个结点有256/4=64个结点...依次类推。所以以下实例的计算方法是:

1*256+3*64=448;1*256+1*64=320 ;2*256+2*64=640;

思路:分别建立两个图像树,将相同层次相同位置的树的结点按规则相加(即和并两颗树),前序遍历树的思想遍历合并后的树(在遍历的同时找到黑色结点,并根据深度计算此结点的像素点数,累加到一个变量中)。需要注意的地方:不同深度上的黑色结点代表的像素点数不同。

代码:

#include <iostream>#include <string>#include <queue>using namespace std;typedef struct tree{char c;struct tree *cnode1,*cnode2,*cnode3,*cnode4;}Tree;Tree *create_node(char c){Tree *node=new Tree;node->c=c;node->cnode1=node->cnode2=node->cnode3=node->cnode4=NULL;    return node;}Tree *create_tree(Tree *root,const string pre_exp,size_t &start){//根据前缀表达式建立树if(start>=pre_exp.size()) return NULL;Tree *node=create_node(pre_exp[start]);if(root==NULL) root=NULL;if(node->c=='p'){node->cnode1=create_tree(root,pre_exp,++start);//递归建立第一个子节点node->cnode2=create_tree(root,pre_exp,++start);//递归建立第二个子节点node->cnode3=create_tree(root,pre_exp,++start);//递归建立第三个子节点node->cnode4=create_tree(root,pre_exp,++start);//递归建立第四个子节点}return node;}void delete_child(Tree *t){//释放树空间if(t){delete_child(t->cnode1);delete_child(t->cnode2);delete_child(t->cnode3);delete_child(t->cnode4);delete t;t=NULL;}}Tree *merge(Tree *root1,Tree *root2){//将树root2合并到root1queue<Tree *> que1,que2;Tree *p1=NULL,*p2=NULL;que1.push(root1);que2.push(root2);while(!que1.empty() && !que2.empty()){//两颗树对应的结点进行合并,如根节点与根节点合并,root1第一个子结点与root2第一个子节点合并,需要一一对应p1=que1.front();p2=que2.front();que1.pop();que2.pop();if((p1->c=='p') && (p2->c=='p')) {que1.push(p1->cnode1);que1.push(p1->cnode2);que1.push(p1->cnode3);que1.push(p1->cnode4);que2.push(p2->cnode1);que2.push(p2->cnode2);que2.push(p2->cnode3);que2.push(p2->cnode4);delete p2;//释放空间}else if(p1->c=='p' && p2->c=='f'){p1->c='f';delete_child(p1->cnode1);delete_child(p1->cnode2);delete_child(p1->cnode3);delete_child(p1->cnode4);p1->cnode1=p1->cnode2=p1->cnode3=p1->cnode4=NULL;delete p2;}else if(p1->c=='e' && p2->c=='f'){p1->c='f';delete p2;}else if(p1->c=='e' && p2->c=='p'){p1->c='p';p1->cnode1=p2->cnode1;p1->cnode2=p2->cnode2;p1->cnode3=p2->cnode3;p1->cnode4=p2->cnode4;}else {delete p2;}}return root1;}int get_depth_pile(int depth){//根据结点深度获取该层次应该具有的像素数int pixels=1024;for(int i=1;i<depth;++i){pixels=pixels/4;}return pixels;}void black_pile(Tree *t,int &pixels,int depth){//前序遍历计算黑色像素数if(t){++depth;if(t->c=='f'){pixels+=get_depth_pile(depth);}black_pile(t->cnode1,pixels,depth);black_pile(t->cnode2,pixels,depth);black_pile(t->cnode3,pixels,depth);black_pile(t->cnode4,pixels,depth);}}void pre_travel(Tree *t){//测试用if(t){cout<<t->c;pre_travel(t->cnode1);pre_travel(t->cnode2);pre_travel(t->cnode3);pre_travel(t->cnode4);}}int main(){int num;cin>>num;while(num--){   string exp1,exp2;   while(cin>>exp1>>exp2){   size_t start=0;   Tree *root1=NULL,*root2=NULL;   root1=create_tree(root1,exp1,start);//建立第一张图像树   start=0;   root2=create_tree(root2,exp2,start);//建立第二章图像树   Tree *root=merge(root1,root2);   int pixels=0;   black_pile(root,pixels,0);   cout<<"There are "<<pixels<<" black pixels."<<endl;   delete_child(root);//释放树空间 //  pre_travel(root);//   cout<<"\n--------------------------"<<endl;   }} return 0;}/*1ppeeefpffeefepefepeefe*/

0 0
原创粉丝点击