2664: 【UVA297】四象树
时间限制: 1 Sec 内存限制: 128 MB提交: 43 解决: 22
[提交][状态][我的提交]
题目描述
四象树是每个内结点均有4个子结点的特殊四叉树,它可用于描述平面上黑白图像。平面上的黑白图像是32行×32列的正方形,每个格子称为1个象素,是最小的图像单位。正方形图像可分成四个相等的小正方形,可按直角座标系四个象限的顺序分别编号1,2,3,4,分别对应于四象树的四个子结点。这样,32行×32列的图像就对应于一棵深度为6的完全四叉树,最底层的每个叶结点正好对应于一个象素。但我们可以压缩四象树的结点数量。
当图像上某个区域为全白或者全黑时,可把该区域在四象树上对应的结点描述为全白(用小写字母e表示)或者全黑(用小写字母f表示),并且对这样的结点不再扩展子结点,因为再扩展出的子树上每个结点都是相同的颜色。
只有当图像上某个区域为“杂色”时,才继续划分成四个子区域(在四象树上对应的结点用小写字母p表示),然后“纯”色的子区域也不再扩展,并继续扩展“杂”色子区域。例如,下图左、中两个图像可分别用它们下边的四象树描述。
我们感兴趣的问题是:当两个大小均为32*32的黑白图像叠加后,合成的新图像是什么样子。合成的规则是:当一个图像上某个区域为全黑时,新图像的这个区域即为全黑;当一个图像上某个区域为全白时,新图像的这个区域的颜色是另加一个图像上这个区域的颜色。上图准确地示例了本合成的规则。
我们给出两个图像对应四象树的先序遍历顺序,求合成后的图像中,黑色象素点的数量。
输入
多组测试数据,第1行一个整数T,表示测试数据的组数,每组数据的格式为:
第1行:一个字符串,描述第1棵四象树的先序序列
第2行:一个字符串,描述第2棵四旬树的先序序列
输出
对每组数据,在单独一行上输出一个整数,表示合成后的图像上黑色象素的数量,格式如输出样例所示:
样例输入
(如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)
3
ppeeefpffeefe
pefepeefe
peeef
peefe
peeef
peepefefe
样例输出
There are 640 black pixels.
There are 512 black pixels.
There are 384 black pixels.
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
using namespace std;
int T,sum,tmp;
bool vis[110][110];
char s[10010];
void dfs(int up1,int up2,int down1,int down2){
char op=s[++tmp];
if(op=='p'){
dfs(up1,up2,(up1+down1)/2,(up2+down2)/2);
dfs(up1,(up2+down2)/2+1,(up1+down1)/2,down2);
dfs((up1+down1)/2+1,up2,down1,(up2+down2)/2);
dfs((up1+down1)/2+1,(up2+down2)/2+1,down1,down2);
}
else if(op=='f')
for(int i=up1;i<=down1;i++)
for(int j=up2;j<=down2;j++)
sum+=(!vis[i][j]),vis[i][j]=1;
}
int main(){
scanf("%d",&T);
while(T--){
memset(s,0,sizeof(s));
memset(vis,0,sizeof(vis));
scanf("%s",s+1),sum=0;
tmp=0,dfs(1,1,32,32);
memset(s,0,sizeof(s));
scanf("%s",s+1);
tmp=0,dfs(1,1,32,32);
printf("There are %d black pixels.\n",sum);
}
return 0;
}