Uva 12166 Equilibrium Mobile
题意:一个天平表达式:[A,B],其中A和B为一个数值或又一个天平表达式。每个天平表达式代表的天平所有长度相等,故如果需要平衡,则要求两边质量相等。题目则是给出了一个天平表达式,要求计算,在给出表达式的情况下,如果要求平横,则最少需要调整几个物体。
思路:假设有N个物体(砝码)在天平上,那么最多需要修改N-1个,因为最差的情况就是照着其中一个点不变,然后其它点都以它为基准,进行调平。
那么,可以这么想,遍历每一个砝码,并以它为基准,最少需要调解多少个?
因为一个天平中,上一层单个点的质量是下一层单个点质量的两倍,那么就可以算出最高层需要的质量为多少。比如第2层中的一个砝码质量为2,那么第一层的质量需要4;
比较每一个点,根据所在层数,计算即可发现如果一个点不变,最高层需要多少质量,最后观察同一质量被需要次数最多是多少。
/*
UvaOJ 12166
Emerald
Mon 27 Jul 2015
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <string>
#include <map>
using namespace std;
string expr;
int needChange;
map<long long, int> hashCount;
// build the binary tree
void BuildTree(string& s, int& start, int root, int layout) {
long long tmp;
if( s[start] != '[' ) {
sscanf( &s[start], "%lld", &tmp );
if( !hashCount.count( tmp<<layout ) ) {
hashCount[tmp<<layout] = 1;
} else {
hashCount[tmp<<layout] ++;
}
} else {
BuildTree(s, ++start, root*2, layout+1);
}
for(; s[start]!=','; start++) {
}
start ++;
if( s[start] != '[' ) {
sscanf( &s[start], "%lld", &tmp );
if( !hashCount.count( tmp<<layout ) ) {
hashCount[tmp<<layout] = 1;
} else {
hashCount[tmp<<layout] ++;
}
} else {
BuildTree(s, ++start, root*2+1, layout+1);
}
}
void Init() {
hashCount.clear();
}
void Solve() {
needChange = 0;
// can't be wasted, if it's forgotten, the case '40' may be wrong
if(expr[0] != '[') {
return ;
}
int pos = 1;
BuildTree( expr, pos, 1, 1 );
map<long long, int> :: iterator it;
int maxC = -1;
int sum = 0;
for( it = hashCount.begin(); it != hashCount.end(); it ++ ) {
sum += it->second;
maxC = maxC > it->second ? maxC : it->second;
}
needChange = sum - maxC;
}
void Print() {
printf("%d\n", needChange);
}
void Read() {
cin >> expr;
}
void Work() {
Init();
Read();
Solve();
Print();
}
int main() {
int T;
cin >> T;
while(T --) {
Work();
}
return 0;
}

浙公网安备 33010602011771号