欢迎访问我的Uva题解目录哦 https://blog.csdn.net/richenyunqi/article/details/81149109
题目描述
题意解析
可以用四分树来表示一个黑白图像,方法是用根结点表示整幅图像,然后把行列各分成两等分,按照图中的方式编号,从左到右对应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;
}