【发布时间】:2016-12-07 06:42:31
【问题描述】:
设置是,给定一个N 对象列表,例如
class Mine
{
public int Distance { get; set; } // from river
public int Gold { get; set; } // in tons
}
将黄金从一个矿山转移到另一个矿山的成本是
// helper function for cost of a move
Func<Tuple<Mine,Mine>, int> MoveCost = (tuple) =>
Math.Abs(tuple.Item1.Distance - tuple.Item2.Distance) * tuple.Item1.Gold;
我想将黄金合并到K 矿场。
我写了一个算法,想了很多遍,但不明白为什么它不起作用。希望我的cmets能帮上忙。知道我哪里出错了吗?
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Mine
{
public int Distance { get; set; } // from river
public int Gold { get; set; } // in tons
}
class Solution
{
static void Main(String[] args)
{
// helper function for reading lines
Func<string, int[]> LineToIntArray = (line) => Array.ConvertAll(line.Split(' '), Int32.Parse);
int[] line1 = LineToIntArray(Console.ReadLine());
int N = line1[0], // # of mines
K = line1[1]; // # of pickup locations
// Populate mine info
List<Mine> mines = new List<Mine>();
for(int i = 0; i < N; ++i)
{
int[] line = LineToIntArray(Console.ReadLine());
mines.Add(new Mine() { Distance = line[0], Gold = line[1] });
}
// helper function for cost of a move
Func<Tuple<Mine,Mine>, int> MoveCost = (tuple) =>
Math.Abs(tuple.Item1.Distance - tuple.Item2.Distance) * tuple.Item1.Gold;
// all move combinations
var moves = from m1 in mines
from m2 in mines
where !m1.Equals(m2)
select Tuple.Create(m1,m2);
// moves in ascending order of cost
var ordered = from m in moves
orderby MoveCost(m)
select m;
int sum = 0; // running total of move costs
var spots = Enumerable.Repeat(1, N).ToArray(); // spots[i] = 1 if hasn't been consildated into other mine, 0 otherwise
var iter = ordered.GetEnumerator();
while(iter.MoveNext() && spots.Sum() != K)
{
var move = iter.Current; // move with next smallest cost
int i = mines.IndexOf(move.Item1), // index of source mine in move
j = mines.IndexOf(move.Item2); // index of destination mine in move
if((spots[i] & spots[j]) == 1) // if the source and destination mines are both unconsolidated
{
sum += MoveCost(move); // add this consolidation to the total cost
spots[i] = 0; // "remove" mine i from the list of unconsolidated mines
}
}
Console.WriteLine(sum);
}
}
我失败的测试用例的一个例子是
3 1
11 3
12 2
13 1
我的输出是
3
正确的输出是
4
【问题讨论】:
-
您是否尝试过设置断点并查看数据?
-
似乎您的代码甚至无法编译。
if(spots[i] & spots[j] == 1)是否符合预期? -
@LucMorin 忽略这个错误
-
我不太确定我是否理解
spots变量的使用,这似乎在您的示例数据中限制为只有 2 个求和操作。你能澄清一下你的想法吗? -
我不得不承认不了解实际目标,因此通过您的代码确实会产生“不希望的”值,但我想了解您是如何达到“希望的”值的。你能用简单的古英语解释这个算法吗?有时在算法上加上文字会“迫使”解决方案公开;-)
标签: c# algorithm linq optimization complexity-theory