紫书刷题记录 UVa297 四分树

感觉紫书上这一部分内容基本都需要递归,也算帮自己初步掌握递归思路了吧!第一次独立完成本章的习题!
本题题意很好理解,但是如果只看书的话最后求总黑方块个数的时候会有疑问,最好还是去看看原题。原题是给定了一共有1024个方块,树的层数不超过5。
这里给出解题思路:按顺序依次建立两颗四叉树->合并树->根据层数求黑色方块总数量,代码很容易实现,就是递归的时候自己多走两遍会比较清晰。下面放出代码(均有注释):

#include
using namespace std;
struct Tree//四叉树 
{
	char val;
	Tree *child[4];
	Tree()
	{
		for(int i=0;i<4;i++)
		child[i]=NULL;
	}
};
int bn,en,sum;//分别代表开始、结束和黑块个数 
Tree *creat(char *tree)//递归建树 
{
	if(bn==en)
    return NULL;
    char ch=tree[bn];
    bn++;
    Tree *root=new Tree();
    root->val=ch;
    if(ch=='p')
    {
    	for(int i=0;i<4;i++)
    	root->child[i]=creat(tree);
    }
    return root;
}
void unionT(Tree * &root1,Tree * &root2)//合并两棵树:这里需要改变指针,所以是对指针的引用; 
{
	if(root1&&root2) 
	{
		char c1=root1->val;
		char c2=root2->val;
        if(c1==c2&&c1=='p')//如果都是中间结点,继续往下执行; 
        {
        	for(int i=0;i<4;i++)
        	unionT(root1->child[i],root2->child[i]);
		}
		else if(c1!='p'&&c2=='p') 
		{
			if(c1=='f')
			return;
			else
			{
				root1=root2;
				return;
			}
		}
		else if(c2=='f')//黑色优先级最大; 
		{
			root1=root2;
			return;
		}
	}
}
void slove(Tree *root,int level)//一共就只有1024个方块,判断层数就很容易能算出黑色结点个数; 
{
	if(root)
	{
		if(root->val=='p')
		{
			for(int i=0;i<4;i++)
			slove(root->child[i],level+1);
		}
		else if(root->val=='f')
		{
		    sum+=1024/(pow(4,level-1));
		}
	}
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		sum=0;
	    char tree1[2001];
	    char tree2[2001];
	    cin>>tree1;
	    cin>>tree2;
	    bn=0,en=strlen(tree1);
	    Tree *root1=creat(tree1);
	    bn=0,en=strlen(tree2);
	    Tree *root2=creat(tree2);
	    unionT(root1,root2);
	    slove(root1,1);
	    cout<<"There are "<<sum<<" black pixels."<<endl;
	}
	return 0;
}

你可能感兴趣的:(紫书刷题记录,算法,数据结构)