UVa 12166(字符型二叉树的dfs)

一.题目

[PDF Link]

A mobile is a type of kinetic sculpture constructed to take advantage of the principle of equilibrium. It consists of a number of rods, from which weighted objects or further rods hang. The objects hanging from the rods balance each other, so that the rods remain more or less horizontal. Each rod hangs from only one string, which gives it freedom to rotate about the string.

We consider mobiles where each rod is attached to its string exactly in the middle, as in the figure underneath. You are given such a configuration, but the weights on the ends are chosen incorrectly, so that the mobile is not in equilibrium. Since that's not aesthetically pleasing, you decide to change some of the weights.

What is the minimum number of weights that you must change in order to bring the mobile to equilibrium? You may substitute any weight by any (possibly non-integer) weight. For the mobile shown in the figure, equilibrium can be reached by changing the middle weight from 7 to 3, so only 1 weight needs to changed.

Input

On the first line one positive number: the number of testcases, at most 100. After that per testcase:
  • One line with the structure of the mobile, which is a  recursively defined expression of the form: 
      <expr> ::= <weight> | "[" <expr> "," <expr> "]"
      with <weight> a positive integer smaller than  109 indicating a weight and  [<expr>,<expr>]  indicating a rod with the two expressions at the ends of the rod.  The total number of rods in the chain from a weight to the top of  the mobile will be at most 16.

Output

Per testcase:
  • One line with the minimum number of weights that have to be changed.

Sample Input

3
[[3,7],6]
40
[[2,3],[4,5]]

Sample Output

103

二.分析与实现

本题很有意思,首先要分析发现,通过“平衡”这个关系,一个叶子就可以决定其他所有叶子的大小,进一步思考,也就是说一个节点就决定了整颗二叉树的大小,所以我们就利用这个性质去判断需要修改多少个节点,因为重量不同的节点所算出来的整颗二叉树点总重量必定也是不同的,所以我们只要搜索所有节点,然后去求每个节点所产生的总重,出现次数最多的总重量就代表有最多的叶子节点不需要进行修改。

三.总结

本题中希望用到这样一种数据结构,能够统计任意类型的数据的出现次数,我们可以采用stl里面的map,遍历和清空的使用方法如下所示,还有一个值得注意的地方就是给定一段字符的s和e,这段字符是一个数字,整理成数字的方法。

#include <iostream>
#include <cstring>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstdio>
using namespace std;
map<long long,int>base;
int sum;
string str;
void dfs(int s,int e,int depth)
{
	if(str[s]=='[')
	{
		///cout<<s<<" "<<e<<endl;
		int p;
		p=0;
		for(int i=s+1;i<=e;i++)
		{
			//cout<<s<<" "<<e<<endl;
			if(str[i]=='[') p++;
			if(str[i]==']') p--;
			if(!p&&str[i]==',')
			{
				dfs(s+1,i-1,depth+1);
				dfs(i+1,e-1,depth+1);
			}
		}
	}
	else 
	{
		long long  w;
		w=0;
		for(int i=s;i<=e;i++)
		{
			w=w*10+str[i]-'0';
		}
		//cout<<w<<endl;
		sum++;
		base[w<<depth]++;
		//printflag();
	}
}
int main()
{
	//freopen("input.txt","r",stdin);
	int T;
	cin>>T;
	for(int t=1;t<=T;t++)
	{

		cin>>str;
		int len;
		base.clear();
		sum=0;
		len=str.length();
		dfs(0,len-1,0);
		int maxn=0;
		for(map<long long,int>::iterator it=base.begin();it!=base.end();++it)
		{
			maxn=max(maxn,it->second);
		}
		printf("%d\n",sum-maxn);
	}
}


 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Java中,二叉树的深度优先搜索(DFS)是一种遍历二叉树的方法。DFS有三种常见的方式:前序遍历、中序遍历和后序遍历。 1. 前序遍历(Preorder Traversal):首先访问根节点,然后递归地遍历左子树,最后递归地遍历右子树。 2. 中序遍历(Inorder Traversal):首先递归地遍历左子树,然后访问根节点,最后递归地遍历右子树。 3. 后序遍历(Postorder Traversal):首先递归地遍历左子树,然后递归地遍历右子树,最后访问根节点。 下面是一个示例代码,展示了如何使用递归实现二叉树DFS: ```java class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int val) { this.val = val; } } public class BinaryTreeDFS { public void preorderTraversal(TreeNode root) { if (root == null) { return; } System.out.print(root.val + " "); preorderTraversal(root.left); preorderTraversal(root.right); } public void inorderTraversal(TreeNode root) { if (root == null) { return; } inorderTraversal(root.left); System.out.print(root.val + " "); inorderTraversal(root.right); } public void postorderTraversal(TreeNode root) { if (root == null) { return; } postorderTraversal(root.left); postorderTraversal(root.right); System.out.print(root.val + " "); } public static void main(String[] args) { TreeNode root = new TreeNode(1); root.left = new TreeNode(2); root.right = new TreeNode(3); root.left.left = new TreeNode(4); root.left.right = new TreeNode(5); BinaryTreeDFS binaryTreeDFS = new BinaryTreeDFS(); System.out.println("Preorder Traversal:"); binaryTreeDFS.preorderTraversal(root); System.out.println("\nInorder Traversal:"); binaryTreeDFS.inorderTraversal(root); System.out.println("\nPostorder Traversal:"); binaryTreeDFS.postorderTraversal(root); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值