12166 - Equilibrium Mobile

 A mobile isa type of kinetic sculpture constructed to take advantage of the principle ofequilibrium. It consists of a number of rods, from which weighted objects orfurther rods hang. The objects hanging from the rods balance each other, sothat the rods remain more or less horizontal. Each rod hangs from only onestring, which gives it freedom to rotate about the string.

We considermobiles where each rod is attached to its string exactly in the middle, as inthe figure underneath. You are given such a configuration, but the weights onthe ends are chosen incorrectly, so that the mobile is not in equilibrium.Since that's not aesthetically pleasing, you decide to change some of theweights.

What is theminimum number of weights that you must change in order to bring the mobile toequilibrium? You may substitute any weight by any (possibly non-integer)weight. For the mobile shown in the figure, equilibrium can be reached bychanging the middle weight from 7 to 3, so only 1 weight needs to change.

Input

On the first lineone positive number: the number of test cases, at most 100. After that per testcase:

  • One line with the structure of the mobile, which is a recursively defined expression of the form:

  <expr> ::= <weight> |"[" <expr> "," <expr> "]"

With <weight> apositive integer smaller than 109 indicating a weightand [<expr>,<expr>]indicating a rod with the two expressionsat the ends of the rod. The total number of rods in the chain from a weight tothe top of the mobile will be at most 16.

Output

Per test case:

  • One line with the minimum number of weights that have to be changed.

Sample Input

3

[[3,7],6]

40

[[2,3],[4,5]]

Sample Output

1

0

3

代码:

#include<iostream>

#include<string>

#include<map>

#include<algorithm>

using namespacestd;

 

string line;

map<long long,int> base;

int sum;

 

void dfs(intdepth, int s ,int e)

{

    if(line[s] == '[')

    {

        int p = 0;

        for(int i = s + 1; i != e; ++i)

        {

            if(line[i] == '[')

            {

                ++p;

            }

            if(line[i] == ']')

            {

                --p;

            }

            if(p == 0 && line[i] ==',')

            {

                dfs(depth + 1, s + 1, i - 1);

                dfs(depth + 1, i + 1, e - 1);

            }

        }

    }

    else

    {

        long long w = 0;

        for(int i = s; i <= e; ++i)

        {

            w = w * 10 + line[i] - '0';

        }

        ++sum;

        ++base[w << depth];

    }

}

 

int main()

{

    ios::sync_with_stdio(false);

    int T;

    cin >> T;

    while(T--)

    {

        cin >> line;

        base.clear();

        sum = 0;

        dfs(0, 0, line.size() - 1);

 

        int maxn = 0;

        for(auto it = base.begin(); it !=base.end(); ++it)

        {

            maxn = max(maxn, it->second);

        }

 

        cout << sum - maxn << endl;

    }

}

解析:

给出数个天平,每个天平的结构都类似于二叉树,只有左右重量都相等时才平衡,求每个天平最少改多少个秤砣,也就是叶子结点可以使得整个天平平衡。天平的深度不超过16。

要使得改动的数量最少,那么就至少有一个秤砣不变,然后以这个秤砣为基准来调整整个天平。天平的结构是二叉树,那么由此我们可以得出,如果以深度为d重量为w的秤砣为基准,那么整个天平的重量就是w * pow(2, d),即w << d。

当然,可能会有一些秤砣算出的以各自为基准的天平总重量相同,设天平总重量为sumw,那么这些秤砣的数量就表示了如果使天平的总重量为sumw需要使多少个秤砣保持不变。

求出所有可能的sumw值以及其对应的秤砣数量,然后在这些sumw值中找到保持不变的秤砣数量中的最大值,设为maxn,设秤砣总数量为sum。那么sum - maxn即为所求。

为了求出sumw对应的秤砣数量,这里用到了STL里的map结构,设为base,那么base[x]表示使天平的重量为x时保持不变的秤砣的数量。在建树时,每当扫描到叶子结点,即秤砣时,算出对应的sumw值,然后另base[sumw]自增1,这样所有的叶子节点都扫完之后,所有可能的sumw值也就算完了。接下来就只需要遍历一遍,找出最大值即可了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值