欢迎访问我的Uva题解目录哦 https://blog.csdn.net/richenyunqi/article/details/81149109

题目描述

例题6-11 四分树(Quadtrees, UVa 297)

题意解析

可以用四分树来表示一个黑白图像,方法是用根结点表示整幅图像,然后把行列各分成两等分,按照图中的方式编号,从左到右对应4个子结点。如果某子结点对应的区域全黑或者全白,则直接用一个黑结点或者白结点表示;如果既有黑又有白,则用一个灰结点表示,并且为这个区域递归建树。
给出两棵四分树的先序遍历,求二者合并之后(黑色部分合并)黑色像素的个数。p表示中间结点,f表示黑色(full),e表示白色(empty)。

算法设计

不需要真的去重建一棵树,只需要进行先根遍历的时候顺便进行统计即可。要注意的是,每一层所代表的黑色像素的结点个数是不一致的。例如,如果根结点作为第一层,当根结点为f时,其代表1024个黑色像素;第二层的一个f结点代表256个黑色像素······,以此类推,每层的一个f结点所代表的黑色像素个数是上层的1/4。具体算法实现可见代码。

C++代码

#include<bits/stdc++.h>
using namespace std;
//image1和image2分别代表两个图像字符串,i1和i2分别代表当前遍历到的两个字符串的字符索引
//pixels代表该层一个f结点代表的黑色像素个数,ans代表最终结果
void DFS(string&image1,int&i1,string&image2,int&i2,int pixels,int&ans){
    if(image1[i1]!='p'&&image2[i2]!='p'){//两个不是父节点
        ans+=(image1[i1]=='f'||image2[i2]=='f')?pixels:0;//有一个是'f'结点,就进行累加
    }else if(image1[i1]=='p'&&image2[i2]=='p'){//两个都是父节点
        for(int i=1;i<=4;++i)//同时遍历其4个子节点
            DFS(image1,++i1,image2,++i2,pixels/4,ans);
    }else if(image1[i1]=='p')//image1处是父节点
        for(int i=0;i<4;++i)//遍历image1的4个子节点
            DFS(image1,++i1,image2,i2,pixels/4,ans);
    else//image2处是父节点
        for(int i=0;i<4;++i)//遍历image2的4个子节点
            DFS(image1,i1,image2,++i2,pixels/4,ans);

}
int main(){
    int n;
    scanf("%d",&n);
    while(n--){
        string line1,line2;
        cin>>line1>>line2;
        int ans=0,i1=0,i2=0;
        DFS(line1,i1,line2,i2,1024,ans);
        printf("There are %d black pixels.\n",ans);
    }
    return 0;
}

相关文章: