首页 新闻 会员 周边

一道acm的题,欢迎一起讨论?

0
悬赏园豆:10 [已解决问题] 解决于 2012-09-18 13:36

Problem Description
Give you a scale and some goods. You should put all the goods on two sides of scale and make the scales balanced.

Input
The first line contains an integer T which is the number of test case.
For each test case, there are two lines of data.
In the first line, there is a single integer n which describes the number of goods.
In the second line, there are n integers. The i-th integer wi is the weight of the i-th corresponding goods. (0 < T ≤ 10, 0 < n ≤ 100, 0 < wi ≤ 100)

Output
For each test case, if all the goods can be put on the scale and make the scales balanced at the same time, output “Yes”, otherwise output “No”.

Sample Input
2
3
1 2 3
3
4 5 6

Sample Output
Yes
No

斗榖於菟的主页 斗榖於菟 | 初学一级 | 园豆:60
提问于:2012-09-18 09:27
< >
分享
最佳答案
1

我的做法:对于n个重量,构建一个深度为n的满二叉树,例如你的第一个例子1,2,3,构建成的满二叉树为:

最后的叶子结点有2^(n-1)个,并约定向左为加法,向右为减法。每个结点的定义为(C#代码,不过你应该能看懂):

class Node
{
     public int Value { get; set; }
}

这里我定义了一个只包含一个字段Value的类Node(原因后面会讲)。Value的含义就是:当遍历到这个Node时,路径上的值。同时需要定义一个Node的集合:

List<Node> nodes = new List<Node>();
nodes.Add(new Node { Value = numbers[0] });

这个nodes表示当前层的所有Node。例如最开始它只包含一个根,这个根就是第一个重量(你例子中的1)。接下来开始遍历这个树:

for (int i = 1; i < numbers.Length; i++)   

numbers就是给出的重量数组{1,2,3}。现在开始处理“2”这个质量,有2种可能:+2或者-2. 那么现在nodes里包含2个结果{ Node(Value = 3),   Node(Value=-1) }。 接下来处理“3”这个质量,之前nodes里有2个结果,那么会被扩展成4个结果:{6,0,2,-4}。那么所有的数都被处理完了,接下来只要检查nodes集合里有没有值为0的,有的话就输出Yes,否则是No。如果题目更难一点,需要输出分组情况的话,那么你需要修改Node类,除了记录当前Value之外,还要保存一个List<Node>,用来记录这个Value是怎么计算出来的。完整C#实现如下:

            var numbers = new[] { 1, 2, 3, 9999, 9000, 444, 555 };    //测试数据

            List<Node> nodes = new List<Node>();
            nodes.Add(new Node { Value = numbers[0] });   //设置根结点

            for (int i = 1; i < numbers.Length; i++)
            {
                var newNodes = new List<Node>();
                foreach (var n in nodes)
                {
                    newNodes.Add(new Node { Value = n.Value + numbers[i] });
                    newNodes.Add(new Node { Value = n.Value - numbers[i] });
                }

                nodes = newNodes;
            }

            Console.WriteLine(nodes.Any(n => n.Value == 0));   //看最后的结果集中是否有值为0的
收获园豆:10
水牛刀刀 | 大侠五级 |园豆:6350 | 2012-09-18 10:47

挺好的方法,谢谢,但是Java里实现起来不是很方便~

斗榖於菟 | 园豆:60 (初学一级) | 2012-09-18 11:19

还有一个问题,我可不可以定义为一个整数int的集合来做。

斗榖於菟 | 园豆:60 (初学一级) | 2012-09-18 11:22

@斗榖於菟: 可以啊,我的那个Node类里就一个int字段,完全可以用一个int数组来实现。

水牛刀刀 | 园豆:6350 (大侠五级) | 2012-09-18 11:34

@斗榖於菟: 为什么在Java里实现起来不方便,我这里的代码完全没有用到任何C#的特性(就算最后一个linq语句,其他语言一个循环就可以了),任何语言实现这一套都是差不多10行代码的事情。

水牛刀刀 | 园豆:6350 (大侠五级) | 2012-09-18 11:35

@水牛刀刀: 好的,我写出来,有些想复杂了,多谢了,希望以后还能和你交流。

斗榖於菟 | 园豆:60 (初学一级) | 2012-09-18 11:59

@斗榖於菟: 验证无误,谢谢~

斗榖於菟 | 园豆:60 (初学一级) | 2012-09-18 13:36
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册