目录

        一、题目大意

        二、理论基础 

        三、解题思路 

        四、参考代码 


一、题目大意

        给n个风铃。每个风铃相当于一个天平(左右各挂一个砝码)并且可以递归定义,判断其维持平衡最少需要修改几个砝码的重量。原题链接

        例:3                        =>1

                [[3,7],6]                  0

                40                          3

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

二、理论基础 

        二叉树:每个节点最多有两个子树的树,具体请查看二叉树

        Map:以键与值的组合为元素({key,value})的数据存取数据结构,具体有多种实现。

        Unordered_map:Map的一种实现,在C++STL标准库中,其底层使用哈希表,内部元素无序,查找速度非常快。

        :参考

数据[[3,7],6] 的二叉树表示

三、解题思路 

        整个风铃可以看作一个递归天平,很明显其可以转换为二叉树(可以通过遍历解决问题)。从整体看一个砝码在天平的重量份额为所在深度乘以实际重量。对于[[3,7],6]中的3,其所在深度为2,天平的重量份额为12,28,12。若所有砝码的重量份额都一致则天平是平衡的,求最少修改砝码数只要用砝码总数减去最多出现次数重量份额的砝码数即可。有多种实现方法,这里采用栈和Unordered_map,详见代码。

四、参考代码 

#include<iostream>
#include<cctype>
#include<cstdio>
#include<stack>
#include<unordered_map>
using namespace std;
typedef unsigned long long ll;

int main() {
	int n;
	stack<char> s;//统计[的数量,其代表了砝码所在的深度
	unordered_map<ll, int> mp;//免去排序,提高速度
	mp.reserve(256);//优化速度
	mp.max_load_factor(0.5);
	ios::sync_with_stdio();
	cin.tie(0);
	cout.tie(0);

	cin >> n;
	while (n--) {
		int max = -1, sum = 0;
		ll ltemp;
		string str;

		cin >> str;
		mp.clear();
		for (int i = 0; i < str.size(); ++i) {
			if (str[i] == '[')
				s.push('[');
			else if (isdigit(str[i])) {
				int j;
				for (j = i; isdigit(str[j + 1]); ++j);
				//使用atoi将字符串转换为整数
				ltemp = (ll)atoi(str.substr(i, j - i + 1).c_str()) << s.size();
				i = j;
				mp[ltemp]++, ++sum;
			} else if (str[i] == ']')
				s.pop();
		}
		for (unordered_map<ll, int>::iterator iter = mp.begin(); iter != mp.end(); ++iter)
			if (max < iter->second)
				max = iter->second;
		printf("%d\n", sum - max);
	}

	return 0;
}

posted on 2024-02-14 21:42  Wayde_CN  阅读(0)  评论(0编辑  收藏  举报  来源