题目大意:给定一颗最大深度为16的二叉树,代表一个天平, 叶节点是一些秤砣,每根杆都悬挂在中间,秤砣重量已知,问最少要修改多少个秤砣的重量才能使天平平衡。
刚看到这道题的时候就发现 - -、 从正面想这道题几乎是无解, 对于一个不平衡的天平根本不知道要改哪边,甚至。。就算是平衡了的天平你也无法确定改不改重量,冥思苦想无所得之后请教他人,发现这题是逆向解Orz,瞬间明白过来了。
对于每个秤砣, 我们可以轻易知道它的深度,然后就可以轻易知道以这颗秤砣为基准,改变其他秤砣之后整个天平的总重量,显然就是 秤砣重量 × 2 ^ 深度,于是就简单了, 求出每个秤砣对应的整个天平的重量M之后, mp[M]++,然后用总天平数减去max(mp[x])就是答案了Orz,太弱了完全没有往逆向解题这个方向考虑。。
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <sstream>
#include <iostream>
#include <algorithm>
using namespace std;
#define ls id<<1,l,mid
#define rs id<<1|1,mid+1,r
#define OFF(x) memset(x,-1,sizeof x)
#define CLR(x) memset(x,0,sizeof x)
#define MEM(x) memset(x,0x3f,sizeof x)
#define rep(i,a,b) for (int i=a;i<b;i++)
#define Rep(i,a,b) for (int i=a;i>=b;i--)
typedef long long ll ;
typedef pair<int,int> pii ;
const int maxn = 1e5+50 ;
const int inf = 0x3f3f3f3f ;
const int MOD = 1e9+7 ;
string s;
map<ll,int> mp;
int main () {
#ifdef LOCAL
freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
#endif
int t;
cin >> t;
while (t--) {
cin >> s ;
mp.clear();
int cnt=0,dep=1;
ll num=0;
for (int i=0;i<s.length();i++) {
if (s[i]=='[') dep <<= 1;
else if (isdigit(s[i])) num=num*10+s[i]-'0';
else {
if (num) {
mp[num*dep]++;
cnt++;
}
num=0;
if (s[i]==']') dep >>= 1;
}
}
if(num) {
mp[num*dep]++;
cnt++;
}
map<ll,int>::iterator it=mp.begin();
int res=0;
while (it!=mp.end()) {
res=max(res,it->second);
it++;
}
cout << cnt-res << endl ;
}
return 0;
}