Uva 12166 严格平衡树
2015-11-14 17:24
375 查看
原题
一开始想得太简单, 直接读数据建立树, 然后像堆调整那样一个个结点检查并向上调整子节点的重量, 后来写到一半发现这样不可行, 需要处理的情况太多, 这样模拟的过程太繁琐了..
于是可耻地google了答案——原来这棵树每层的结点值都是满足一定规律的,在同一层上的结点值必须相等, 而且上层的值是下一层的节点值的两倍。
认识到这个规律后,还是需要做一点巧妙的处理(方法来自这里 ) :
由于只要选择一个叶节点作为标准就可以确定一棵树的总重量,
因此遍历每个叶节点, 确定以其作为标准时树的总重量,
那么最多叶节点对应的那个总重量就是树应该取的最终总重量 M,
用总的叶结点数减去M所对应的叶节点数即可得到需要改变的叶节点数.
还有一个需要注意的地方就是由于结点的值正好压了int的范围, 所以树的总重量肯定有可能超过int, 因此要用 long long 来存储树的总重量
以下为模仿答案写的代码:
一开始想得太简单, 直接读数据建立树, 然后像堆调整那样一个个结点检查并向上调整子节点的重量, 后来写到一半发现这样不可行, 需要处理的情况太多, 这样模拟的过程太繁琐了..
于是可耻地google了答案——原来这棵树每层的结点值都是满足一定规律的,在同一层上的结点值必须相等, 而且上层的值是下一层的节点值的两倍。
认识到这个规律后,还是需要做一点巧妙的处理(方法来自这里 ) :
由于只要选择一个叶节点作为标准就可以确定一棵树的总重量,
因此遍历每个叶节点, 确定以其作为标准时树的总重量,
那么最多叶节点对应的那个总重量就是树应该取的最终总重量 M,
用总的叶结点数减去M所对应的叶节点数即可得到需要改变的叶节点数.
还有一个需要注意的地方就是由于结点的值正好压了int的范围, 所以树的总重量肯定有可能超过int, 因此要用 long long 来存储树的总重量
以下为模仿答案写的代码:
#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> #pragma warning(disable:4996) //关掉4996警告 /* Uva 439 关键 : 1. 事先找出规律!!! 2. 技巧 : 由于只要选择一个叶节点作为标准就可以确定一棵树的总重量, 因此遍历每个叶节点, 确定以其作为标准时树的总重量, 那么 最多叶节点对应的那个总重量就是树应该取的最终总重量 M, 用总的叶结点数减去M所对应的叶节点数即可得到需要改变的叶节点数 */ using namespace std; int Leaves; string input; int ptr; map<long long, int> WeightNum; // 记录树的某个总重量所对应的标准结点数 void Build(int Depth) { char ch; ch = input[ptr++]; if ( ch == '[' ) { Build(Depth+1); ch = input[ptr++]; // 读 ',' Build(Depth+1); ch = input[ptr++]; // 读 ']' }else { // 找到一个叶节点 long long sum = 0; do { sum = sum * 10 + ch - '0'; ch = input[ptr++]; } while ( ptr < input.size() && ch != ',' && ch != ']' ); ptr--; WeightNum[sum << Depth]++; Leaves++; } return; } int main( ) { //freopen("input.txt", "r", stdin); int N; cin >> N; for ( int i = 0; i < N; i++ ) { WeightNum.clear( ); cin >> input; Leaves = ptr = 0; Build(0); int mostNum = 0; for ( auto it = WeightNum.begin( ); it != WeightNum.end(); it++ ) { mostNum = max(mostNum, it->second); } cout < a0f9 ;< Leaves - mostNum << endl; } //system("pause"); return 0; }
相关文章推荐
- 九度OJ 1283:第一个只出现一次的字符 (计数)
- MongoDB小结01 - MongoDB简介
- 九度OJ 1283:第一个只出现一次的字符 (计数)
- 测试准备工作《全程软件测试》
- AS(AndroidStudio)快捷键
- Java Web(2)Hibernate 集成使用
- poj 2393
- cenos7.1 安装openstack kilo 心得之四 安装OpenStack包
- Android开发 设计模式(一、Singleton(单例模式))
- js快速找出数组中的最大值
- IO重定向
- MEF等Ioc框架引起内存泄露-PartCreationPolicy
- 游戏项目中的资源加载管理
- servlet使用json案例,提供jar文件下载
- 个人博客week7
- TS科普10 自适应字段
- 九度OJ 1262:Sequence Construction puzzles(I)_构造全递增序列 (DP)
- 九度OJ 1262:Sequence Construction puzzles(I)_构造全递增序列 (DP)
- [windows]快速从ftp下载最新软件包的批处理脚本
- 4.2.4 Python特有编码