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;
}