我有数量不定的项目,我想在不定的时间内分配。我遇到的问题是如何分配剩余部分,以便“悬垂”之间的空间尽可能相等。例如,如果我有 13 个项目 (X) 分布在 5 小时内,我想结束
Hours: 1 2 3 4 5
---------------------------------
x x x x x
x x x x x
x x x
我不确定我是不是想多了。我目前正在检查项目数量是否大于小时数。如果那是真的,我将除以(项目数/小时数)。然后我认为我必须除以(小时数/剩余时间)...但是对于上面的示例:5/3=1.6,四舍五入为 2。我认为我必须使用 Math.Floor
以某种方式,但我目前不确定如何。
对于 5 小时内的 4 项,我想以 X 结尾 对于带有 Ys 的 2 个项目 对于带有 Zs 的 1 个项目
1 2 3 4 5
------------------------
x x x x
y y
z
项目数量和小时数是可变的。
好的,我认为我目前正走在正确的轨道上。我现在正试图将垃圾箱分成两半,并将剩余的一个放在中央垃圾箱中。递归重复,直到余数为 0。
最佳答案
编辑:修复了偶数小时和项目的问题。
这是一个难题,下面是解决方案。我已经为一个完全通用的问题编写了解决方案,因此它适用于任意时间和项目数量。这是示例输出:
Items=10, Hours=14
XX XX XX XX XX
Items=11, Hours=14
XX XXXXX XX XX
Items=12, Hours=14
XX XXXXXXXX XX
Items=16, Hours=13
XXXXXXXXXXXXX
XXX
Items=17, Hours=13
XXXXXXXXXXXXX
X X X X
Items=18, Hours=13
XXXXXXXXXXXXX
X XXX X
Items=19, Hours=13
XXXXXXXXXXXXX
X X X X X X
Items=20, Hours=13
XXXXXXXXXXXXX
X X XXX X X
Items=21, Hours=13
XXXXXXXXXXXXX
X XX X X XX X
以下是解决方案的工作原理:
- 填充行的数量是微不足道的,你可以通过 (items/hours) * hours 得到它。
- 最后一行是需要所有魔法的地方。
- 当剩余项目的数量为奇数时,我们要打开中心。如果小时数也是奇数,则中心定义明确,否则我们就不走运了,在这种情况下我们会出现一些“不平衡”。
- 对于偶数项,我们将它们配对并按平衡二叉树的顺序分配每对。这基本上意味着我们首先将每一对放在最后。然后下一对中途并递归地遵循模式。这可能是最难理解的部分,因此建议使用纸和笔:)。
代码如下:
static void Main(string[] args)
{
var hours = 13;
for (var items = 16; items < 22; items++)
PrintDistribution(items, hours);
}
private static void PrintDistribution(int items, int hours)
{
Console.WriteLine(string.Format("\nItems={0}, Hours={1}", items, hours));
for (var i = 0; i < (items / hours) * hours; i++)
{
Console.Write('X');
if ((i + 1) % hours == 0)
Console.WriteLine();
}
var line = new StringBuilder(new string(' ', hours));
var remaining = items % hours;
var evens = remaining / 2;
var odd = remaining - (evens * 2);
var seq = BinaryTreeSequence(hours / 2).GetEnumerator();
for (var i = 0; i < evens; i++)
{
seq.MoveNext();
line[seq.Current] = 'X';
line[hours - seq.Current - 1] = 'X';
}
if (odd > 0)
if (hours % 2 == 0)
{
seq.MoveNext();
line[seq.Current] = 'X';
}
else
line[hours / 2] = 'X';
Console.WriteLine(line);
}
public static IEnumerable<int> BinaryTreeSequence(int count)
{
if (count > 1)
yield return count - 1;
if (count > 0)
yield return 0;
var seqQueue = new Queue<Tuple<int, int, int>>();
Enqueue(seqQueue, 0, count - 1);
for (var seqIndex = count - 2; seqIndex > 0; seqIndex--)
{
var moreNeeded = seqQueue.Count < seqIndex;
var seq = seqQueue.Dequeue();
yield return seq.Item1;
if (moreNeeded)
{
Enqueue(seqQueue, seq.Item1, seq.Item3);
Enqueue(seqQueue, seq.Item2, seq.Item1);
}
}
}
private static void Enqueue(Queue<Tuple<int, int, int>> q, int min, int max)
{
var midPoint = (min + max) / 2;
if (midPoint != min && midPoint != max)
q.Enqueue(Tuple.Create(midPoint, min, max));
}
关于c# - 在几个小时内平均分配项目数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19962065/