UVa 12166 修改天平

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3318

题意:给一个深度不超过16的二叉树,代表一个天平。每根杆悬挂在中间,每个秤砣的重量已知,至少修改多少个秤砣的重量才能让天平平衡?

要让天平平衡,必须以其中一个秤砣作为标准,然后修改其余的秤砣。当以深度为d,值为x的叶子节点作为标准时,可以发现此时天平的总质量为x<<d。

因此可以遍历二叉树的每个叶子节点,在这里可以使用map容器,计算出秤砣总质量m所出现的次数,并且记录叶子节点数量number。这样,最后(number-map容器中最大的数)即为修改的最少次数。

一开始我不明白为什么要w*10,直接w<<depth不就行了,后来意识到如果是多位数就需要*10了...

 1 #include<iostream>
 2 #include<map>
 3 #include<cstring>
 4 #include<string>
 5 #include<algorithm>
 6 using namespace std;
 7
 8 int number;
 9 string line;
10 map<long long, int> ans;
11
12 void dfs(int depth, int s, int length)
13 {
14     if (line[s] == ‘[‘)
15     {
16         int p = 0;
17         for (int i = s + 1; i<length; i++)
18         {
19             if (line[i] == ‘[‘)  p++;
20             if (line[i] == ‘]‘)  p--;
21             if (p == 0 && line[i] == ‘,‘)
22             {
23                 dfs(depth + 1, s + 1, i-1);
24                 dfs(depth + 1, i + 1, length - 1);
25             }
26         }
27     }
28     else {
29         long long w = 0;
30         for (int i = s; i <= length; i++)
31             w = w * 10 + line[i] - ‘0‘;
32         ++number;
33         ++ans[w << depth];
34     }
35 }
36
37 int main()
38 {
39     int t;
40     int maxn;
41     cin >> t;
42     while (t--)
43     {
44         cin >> line;
45         ans.clear();
46         number = 0;
47         dfs(0, 0, line.size()-1);
48         maxn = 0;
49         map<long long, int>::iterator it = ans.begin();
50         for (; it != ans.end(); it++)
51         {
52             maxn = max(maxn, it->second);
53         }
54         cout << number - maxn << endl;
55     }
56     return 0;
57 }
时间: 2024-12-20 18:28:42

UVa 12166 修改天平的相关文章

UVA - 12166 Equilibrium Mobile (修改天平)(dfs字符串表示的二叉树)

题意:问使天平平衡需要改动的最少的叶子结点重量的个数. 分析:天平达到平衡总会有个重量,这个重量可以由某个叶子结点的重量和深度直接决定. 如下例子: 假设根结点深度为0,结点6深度为1,若以该结点为基准(该结点值不变),天平要平衡,总重量是12(6 << 1),而若以结点3为基准,天平要平衡,总重量也是12(3 << 2). 由此可得,只需要算出以每个结点为基准的总重量,若该重量下对应的叶子结点最多,则使天平在此重量下平衡改变的叶子结点数最少. #pragma comment(li

习题6-6 修改天平 UVa12166

1.题目描述:点击打开链接 2.解题思路:本题利用dfs解决,不过思维上要发挥一些创造性.本题问至少要修改的砝码个数,那么首先可以想到要选一个基准砝码,其他所有的砝码都试图根据这个基准法吗而改变.不过本题的巧妙之处就在这里,只要以深度为depth(depth从0开始)重量为w的砝码为基准,那么就能求出整个天平的总重量,即w*2^(depth),在代码中可以简洁地表示为w<<depth.这样,我们只用统计每个可能的总重量对应了多少不需要改动的砝码,设一共有sum个砝码,总重量为sumw的天平对应

UVA 12166 Equilibrium Mobile

直接贪心嘛.先想想最后平衡的时候,如果知道了总重量,那么每一个结点的重量其实也就确定了. 每个结点在左在右其实都不影响,只和层数有关.现在反过来,如果不修改某个结点,那么就可以计算出总质量,取总质量出现次数最多的保持不变. /********************************************************* * --------------Tyrannosaurus--------- * * author AbyssalFish * ***************

uva 12166 bfs

这一题与白书上的一题关于天平的题目有些相似 uva839 #include <iostream> #include <cstdio> #include <cstring> using namespace std; bool solve(int& w){ int w1,w2,d1,d2; cin >> w1 >> d1 >> w2 >> d2; bool b1 = true,b2 = true; if(!w1) b1

UVa 12166(字符型二叉树的dfs)

一.题目 [PDF Link] A mobile is a type of kinetic sculpture constructed to take advantage of the principle of equilibrium. It consists of a number of rods, from which weighted objects or further rods hang. The objects hanging from the rods balance each o

UVa 1354 Mobile Computing | GOJ 1320 不加修饰的天平问题

传送门1(UVa): https://uva.onlinejudge.org/external/13/1354.pdf 传送门2(GOJ): http://acm.gdufe.edu.cn/Problem/read/id/1320 题意: 长度限制 r (1 < r < 10), 给 n (1 <= n <= 6) 个砝码,组成平衡(考虑重量和力臂)的天平,求天平最长能多长. 2015个人选拔赛#6 1004 比赛的时候完全不知道怎么做,比赛完两天重新看一遍有点思路就是敲不出来(弱

UVa 10012 有多大 没AC,待修改

题意:给出一些圆的半径,把所有圆放到一个矩形里,要求所有圆都必须与矩形的最下边相切,求矩形的最小长度. 本来写得很快,以为是一道水题,结果有太多情况没考虑..我是按照最左圆的半径加上每两相切圆的圆心间水平距离再加上最右圆的半径写的,有太多情况没考虑.一会补上一个,缝缝补补的,现在都有些晕了,现在还遗漏的情况是,我只考虑了第二个圆比第一个圆能到更左,以及倒数第二个圆比倒数第一个圆能到更右,但是第三个圆或第四个圆也可能比它左边的圆更能到达左边的,右边类似..这就像,只补上了i-2号圆与i号圆相切,而

HDU 1754 - I Hate It &amp; UVA 12299 - RMQ with Shifts - [单点/区间修改、区间查询线段树]

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754 Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感.不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问.当然,老师

UVA 11987 Almost Union-Find (单点修改的并查集)

此题最难处理的操作就是将一个单点改变集合,而普通的并查集是不支持这种操作的. 当结点p是叶子结点的时候,直接pa[p] = root(q)是可以的, p没有子结点,这个操作对其它结点不会造成任何影响, 而当p是父结点的时候这种操作会破坏子节点的路径,因此必须保留原来的路径. 我们希望pa[p] = root(q)的同时又保留原来的路径,那么只需要在点上做一个标记, 如果这个点被标记,就沿着新的路径寻找. 此时在修改操作的时候这个点一定是叶子结点,所以可以直接pa[p] = root(q), 而且