您的位置:首页 > 产品设计 > UI/UE

UVA - 12166 Equilibrium Mobile

2017-10-28 21:47 323 查看
/*

题目链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3318
要点:

我觉得,这题主要是考察思维,而不是考察技巧

当然,还是有一点点技巧的,就是不用这个就会有些麻烦,比如map 的巧妙应用,就算是一个技巧

其实这题的思路也比较巧,就是对每个叶子结点,按照其深度,来推出如果以该叶子结点为基准,整棵树的质量

然后便能统计出每种总重量,各由多少个叶子结点推出,我们选最多的那个总重量,来保证需要修改的叶子最少

本题的巧妙之处就在于,只要以深度为depth(depth从0开始)重量为w的砝码为基准,那么就能求出整个天平的总重量,即w*2^(depth),在代码中可以简洁地表示为w<<depth。这样,我们只用统计每个可能的总重量对应了多少不需要改动的砝码,设一共有sum个砝码,总重量为sumw的天平对应的砝码个数是base[sumw],那么最终答案就是sum-max{base[i]}(i为所有可能的天平总重量)

查阅题解:
http://m.blog.csdn.net/hao_zong_yin/article/details/73028817 http://blog.csdn.net/u013555159/article/details/51356003 http://blog.csdn.net/crazysillynerd/article/details/43876123 http://www.bubuko.com/infodetail-714729.html */

#include <iostream>
#include <string>
#include <map>
#include <cctype>
#define rep(i, n) for (int i = 0; i < (n); i++)
typedef long long ll;
using namespace std;

int main()
{
string s;
map<ll, int> m;
map<ll, int>::iterator it;

int t;
cin >> t;
while (t--)
{
cin >> s;
m.clear();

int depth = 0, leaves = 0, sw_max = 0; // 分别为 当前深度、当前已找到的叶子数,以及 same wight _max,表示叶子重量出现的最多次数,我们取这个最多次数,把与之不同的进行修改,最后得到的就是最小修改次数
rep(i, (int)s.size())
{
if (s[i] == '[') depth++;
else if (s[i] == ']') depth--;
else if (isdigit(s[i]))
{
leaves++;
ll weight = 0;
while (isdigit(s[i]))
{
weight = weight * 10 + s[i++] - '0';
}
weight <<= depth;
m[weight]++;
i--;
}
}
for (it = m.begin(); it != m.end(); it++)
sw_max = max(sw_max, it->second);
cout << leaves - sw_max << endl;
}
return 0;
}

/*

  而贴出的其他题解链接,基本上都是用bfs的思路,也即:

  

  在每次出现逗号,且深度相对参数为0时(注意,这个地方有点奇妙,深度不是真正为0,而只是相对参数为0),将树分为左子树和右子树

  

  然后再对左右子树按照这样的思路来递归,直到这个参数表示的范围内,找不到任何 "[",或是"]",或是"," 

  此时就说明,我们已经把该参数范围里的所有特殊符号剔除,剩下的范围可以表示一个叶子,我们就可以求叶子的重量,再结合其深度,推出根节点位置的重量

  

  其他的思路,与上一种思路基本一致

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM uva