UVA-12166-Equilibrium Mobile【思维】【二叉树】【好题】

UVA-12166-Equilibrium Mobile【思维】【二叉树】【好题】_第1张图片
UVA-12166-Equilibrium Mobile【思维】【二叉树】【好题】_第2张图片

题目链接:UVA-12166

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

类似于给出一颗树,使得这棵树平衡。即,每一颗子树的左右都平衡。

只有子节点有值,如下图,红色节点为虚拟节点值

UVA-12166-Equilibrium Mobile【思维】【二叉树】【好题】_第3张图片

所以将 7 ->改为 3 即可

题目思路:递归构造树,当前子节点的值为w,深度为d, 则他的价值为w * pow(2, d),即w << d

将每一个子节点递归到根节点,算出他的价值,用mp记录。
记:价值出现的次数最多的为max_cnt(标准节点)
记:子节点个数为cnt个
答案 -> cnt - max_cnt。 (其他节点改为标准节点)

参考博客:here

以下是代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
string s;
int cnt = 0; //记录子节点个数
int ans = 0;
map <long long, int> mp;
void solve(int cur, int b, int len)  //层数,开始位置,长度
{
    if (s[b] == '[')
    {
        int p = 0;
        for (int i = b + 1; i < len; i++)
        {
            if (s[i] == '[') p++;
            if (s[i] == ']') p--;
            if (p == 0 && s[i] == ',')
            {
                solve(cur + 1, b + 1, i - 1);
                solve(cur + 1, i + 1, len - 1);
            }
        }
    }
    else
    {
        long long w = 0;
        for (int i = b; i <= len; i++)
        {
            w = w * 10 + s[i] - '0';
        }
        cnt++;
        mp[w << cur]++;
        ans = max(ans, mp[w<int main()
{
    int _;
    cin >> _;
    while(_--)
    {
        cin >> s;
        mp.clear();
        cnt = 0;ans = 0;
        solve(0, 0, s.size() - 1);
        cout << cnt - ans << endl;
    }
    return 0;
}

你可能感兴趣的:(ACM_思维,ACM解题报告)