UVA - 12166 Equilibrium Mobile(括号处理+二叉树+数论(?))

虽然在上边写了二叉树但是确实不关二叉树的事情。

这是一个关于天平平衡以及要不要改动的问题。

乍看其实是简单的,但是渐渐会发现这东西和我的代码一样,牵一发动全身(= =|||)。

我第一个想法是找到第一个叶子,然后和边上的比,那么问题来了,如果不一样改哪个叶子,都改?绝对超时鸭。

再想,从下到上,每一个合起来的重量和边上的比,看起来好像靠谱很多,但是问题又来了,叶子很多的时候,再统一就很多,我们假设这是一棵完美二叉树,这个时候可以统计叶子上最多的数字,如果123456呢?一样的超时。

然后就怎么也想不到了。

一心只有暴力……

看了大佬的博客,不妨固定一个,看一下整体会是多重。

然后d层深的节点,有w重,那么这个节点只要不变,那么整体就是w*pow(2*d)重,我数学差没法证明,有会的小伙伴可以在评论帮帮我(= =|||),稍稍可以理解,因为后一层的节点的和一定会是上一层的和,只是分的散和是一样的……

然后问题又来了,我处理不了括号,因为和深度有关,所以深度是必要的。

纠结了半天还是照着博客的写了,博客的明明也没有高深异常,但就是想不到纠结……

再想想其他的……

#include <iostream>
#include <cstring>
#include <cmath>
#include <string>
#include <map>
using namespace std;

int all;
string t;

map<long long, int>m;
void dfs(int l, int r,int deep)
{
	if (t[l]=='[')
	{
		int p = 0;
		for (int i = l + 1; i < r; i++)
		{
			if (t[i] == '[')
				p++;
			else if (t[i] == ']')
				p--;

			if (p == 0 && t[i] == ',')
			{
				dfs(l + 1, i - 1, deep + 1);
				dfs(i + 1, r - 1, deep + 1);
			}
		}
	}
	else
	{
		long long sum = 0;
		for(int i = l; i <= r; i++)
		{
			sum *= 10;
			sum += (t[i] - '0');
		}
		sum = sum * pow(2, deep);
		m[sum]++;
		all++;
	}
}

int max(int a, int b)
{
	return a > b ? a : b;
}

int main()
{
	int T;
	cin >> T;
	while (T--)
	{
		m.clear();
		cin >> t;
		all = 0;
		dfs(0, t.length() - 1, 0);
		map<long long, int>::iterator it;
		int maxn = -1;
		for (it = m.begin(); it != m.end(); it++)
		{
			maxn = max(maxn, it->second);
		}
		cout << all - maxn << endl;
	}


	//system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42191950/article/details/83544632