有点烦的一题, 也是计算节点的值, 但是有两棵树, 取两棵树的并集, 也就是两棵树同一个节点的值要尽量取大的
方法很多, 基本上也都是需要给每个结点存一个值, 这个值等于其四个子节点的值之和, 以此类推
这次试了一个以前没用过的方法, 因为子节点的数目是固定的, 所以想给每个结点赋一个ID, 然后用map记录结点的值
子节点从左到右标上序号1,2,3,4, ID就是从根节点(100000)到这个结点的路径上的结点序号串起来
每读一棵新的子树就要记录其四个子节点的值之和, 然后与子树根节点之前的值比较, 更新
一开始还犯了一个错误, 树的深度指的是从根节点到某个结点的路径的长度,
这样根节点的深度应该为0, 而深度不超过5的树最多可以有六层结点
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <list>
#include <cassert>
#include <iomanip>
using namespace std;
const int MAXN = 1500;
const int BASE = 10;
typedef long long LL;
/*
uva 297
关键 : 1. depth is not more than 5 则最长的路径上有6个结点
2. 给每个node给一个六位数整数作为ID, 即从根节点(根节点为100000)到达这个结点的路径
如ID最大的结点为144444
*/
map<int,int> mark;
int Calc(int parent,int deep){
char ch;
// cout << parent << " " << deep << endl;
int NodeNum = 4, ThisSum = 0, t, markNum = parent;
if( deep==0 ) NodeNum = 1;
for(int i=1; i<=NodeNum; i++){
cin >> ch;
markNum = parent+i*pow(BASE,5-deep);
t = 0;
if( ch=='p' ){
t = Calc(markNum,deep+1);
}else if( ch=='f' ){
t = 1024>>(2*deep);
}
if( t>mark[markNum] ){
mark[markNum] = t;
// printf("1.mark[%d]=%d\n",markNum,t);
}
ThisSum += mark[markNum];
}
if( ThisSum>mark[parent] ){
mark[parent] = ThisSum;
// printf("2.mark[%d]=%d\n",parent,ThisSum);
}
return ThisSum;
}
int main(){
// freopen("input2.txt","r",stdin);
int T;
cin >> T;
while( T-- ){
mark.clear();
Calc(0,0); // 根节点为第0层 , deep = 0
Calc(0,0);
printf("There are %d black pixels.\n",mark[0]);
}
return 0;
}