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;
}

 

posted @ 2015-07-29 21:36  Emerald  阅读(1143)  评论(0编辑  收藏  举报