1. 程式人生 > >12166 Equilibrium Mobile(括號處理+二叉樹+數論(?))

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