【问题标题】:Algorithm to divide a chocolate bar in equal parts将巧克力棒分成等份的算法
【发布时间】:2009-05-13 19:27:33
【问题描述】:

一个随机的想法突然出现在我的脑海中(当然是在我分享巧克力棒的时候!)。我想知道是否有通用算法来解决这个问题。

问题是这样的:

信息

1. 你有一块巧克力棒,上面有排列成矩形矩阵的小方块
2.房间里有n个人

问题

编写一个算法,输出最优配置 (p x q),其中条形可以在 n, n-1, n-2...., 2, 1 人之间平均共享,但有以下限制:

1.小方块(单位方块)不能切成小块
2.所有中断都必须完全沿一个轴进行
3。休息的总数不能超过 n(这是为了阻止低效的解决方案,例如尝试将整个酒吧分成小块并将小块分成小块)
4。 p 或 q 不能等于 1。yx 在其中一个答案中指出,如果一侧有 1 bar,则问题很容易解决。然而,对于现实世界的情况,这并不是一个好的解决方案 - 这是解决这个问题的目的 :)

示例

对于 n = 4,最优配置为 4 x 3。

 ~~~~ ~~~~ ~~~~ ~~~~
|    |    |    |    |
 ~~~~ ~~~~ ~~~~ ~~~~
|    |    |    |    |
 ~~~~ ~~~~ ~~~~ ~~~~
|    |    |    |    |
 ~~~~ ~~~~ ~~~~ ~~~~

此配置可分为:

4人沿垂直轴3个休息
3人沿水平轴2个休息
2人1个休息在中间
br>
其他经验解决方案是 (n, p, q) = (1, 1, 1); (2, 2, 1); (3, 3, 2); (4, 4, 3); (5, 5, 12); (6, 6, 10) OR (6, 5, 12)

澄清
如果适用,中断定义为沿条形子集的一个轴的切割。为了更好地说明这一点,假设您有一个像这样的 2 x 2 巧克力棒:

 ~~~~ ~~~~
|    |    |
 ~~~~ ~~~~
|    |    |
 ~~~~ ~~~~

传统观点认为,您需要进行 2 次中断(中间的垂直轴 - 向下和交叉)才能将此条分成 4 块。然而,在现实世界中(如果它是一块巧克力棒),你会先把它分成两半,然后再分别分开每一半。这总共有 3 次休息 - 1 次休息在整个酒吧,2 次休息在 2 个不同的酒吧子集。

我在互联网上的任何地方都找不到解决方案 - 如果有人觉得这不是编程相关问题或解决方案已经存在,请随时关闭问题 =)

【问题讨论】:

  • 你的规则太严格了,为了把任何东西分成 n 部分,你至少需要 n-1 次休息,但是因为休息必须沿着一个边缘并且不能占到一小块分成两个你也不能做复合休息(在你的澄清部分),你问的是不可能的。
  • @yx 这个问题需要用最多 n 次中断来打破条形。我认为您不需要进行复合休息来实现限制 - 我有一个最多 n = 8 的解决方案(当然是手工完成)。
  • 那么解决方案只需要输出 p 和 q 而不需要在哪里打破它们?
  • 如果您寄给我们一块巧克力棒,我们可以尝试处理它。十几个会好得多,因为那样我可能想和我的朋友一起进行一些测试。没有葡萄干,没有气泡。深色或牛奶,请。
  • 可以做蛋糕:bbc.co.uk/dna/h2g2/A27360038.

标签: algorithm geometry 2d


【解决方案1】:

在我看来,您正在寻找可以被 1 到 n 之间的所有数字整除的数字。这称为 1, ..., n 的最小公倍数。根据定义,包含 1, ..., n 平方的最小公倍数的正方形可以均匀地分成大小为 1, ..., n 的块。您正在寻找最多 n 次拆分,这会增加问题的额外复杂性,这可能是可能的,也可能是不可能的。

n = 4 的示例是 LCM(4,3,2,1),即 12。LCM(5,4,3,2,1) 是 60。LCM(6,5,4,3, 2,1) 也是 60。

它们总是可以布置成 1xLCM(n,...,1) 矩形,并且总是可以分成 1,...,n 个偶数堆,分成 n-1 或更少的分区。

例如,当n = 4时,LCM(4,3,2,1) = 12。矩形为

############

又可以分为:

1: ############     // 0 cuts
2: ###### ######    // 1 cut
3: #### #### ####   // 2 cuts
4: ### ### ### ###  // 3 cuts (3 being n-1)

【讨论】:

  • 该死,我正要按照尺寸为 1x(LCM(factors(n-1))) 的矩形巧克力来发布这个答案
  • @Welbog 最大休息时间为 n;不是 n -1。正如 yx 所指出的,n - 1 是将条形分成 n 块所需的最少休息次数。 n, n - 1, n - 2...2, 1 的 LCM 定义了 bar 的大小,但不定义配置
  • @roy100:查看我的最新更新。没关系,因为您始终可以在 n-1 或更少的间隔中使用 1-by-LCM 矩形进行此操作。
  • 抱歉 - 忘记添加该限制。 p != q != 1.
  • 噢噢噢噢!在我解决问题之后改变问题的性质,是吗?这太粗鲁了。
【解决方案2】:

由于您不能一次切割多个片段,因此对于您想要的任意数量的片段 m,其中 m 在集合 (1..n) 中,您将始终需要 m-1 次切割。每次切割都会多制作一件,您从一件开始。

在之前的解决方案的基础上,我认为您正在直观地寻找以下算法:

A = LCM(n)
p = greatest divisor of A <= sqrt(A)
q = A/p

用于此的算法应该很简单,(例如,从 p = floor(sqrt(A)) 开始,然后倒计时直到 mod(A,p) == 0)。

您需要 sqrt 的原因是限制您检查的数字数量。毕竟,你总是有一个除数 = sqrt(A)

【讨论】:

  • 是的——没错。希望我可以将其标记为已接受的答案,但这对 Welbog 不公平 =) sqrt 的数学意义是什么?
【解决方案3】:

回答这个问题的一个好方法是使用广度优先搜索算法。该算法将尝试整个巧克力棒的所有可能断裂。然后针对问题的每一种可能状态,尝试所有可能的中断,这将继续进行,同时跟踪各个部分的均匀性。

我想补充一点,规则将强制巧克力棒的哪些休息是合法的,而那些不合法的可能状态会从算法中剔除。

【讨论】:

    猜你喜欢
    • 2017-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多