公平分享披萨


13

与朋友共享披萨的困难在于,很难确保每个人都得到相同数量的意大利辣香肠。因此,您的任务是决定如何公平地切片披萨,以便每个人都开心。

方向

编写一个程序,给定圆形比萨饼上意大利辣味香肠的位置列表和要制作的切片数量,输出一个程序,将比萨饼切成的角度列表,以使每个切片上的比萨饼数量相同它。

  • 披萨只有一个馅料:意大利辣香肠。
  • 您的朋友不在乎切片的大小,只是他们没有从任何意大利辣香肠中被骗。
  • 比萨饼是一个以原点为中心的圆(0, 0)半径为1
  • 意大利辣香肠是圆心,只要输入内容表明它们居中且半径为0.1
  • 将输入作为代表要制作的切片数量的整数,以及代表意大利辣香肠在直角坐标系上的位置的有序对列表。(以任何合理的格式)
  • 输出应该是一个以弧度表示的角度列表,该角度表示比萨的“切口”的位置(在范围内0 <= a < 2pi)。(以任何合理的格式)(精度至少应为+/- 1e-5。)
  • 您可以在切片上放上一部分意大利辣香肠(例如,如果一个比萨饼上有一个意大利辣香肠,并且需要由10个人共享,则将比萨切成10次,全部切成薄片切成意大利辣香肠。但是要确保它是公平的) !)
  • 切成薄片(可能必须)切成多个意大利辣味香肠。
  • 意大利辣味香肠可能会重叠。

例子

输入:

8 people, pepperonis: (0.4, 0.2), (-0.3, 0.1), (-0.022, -0.5), (0.3, -0.32)

可能的有效输出:

slices at:
0, 0.46365, 0.68916, 2.81984, 3.14159, 4.66842, 4.86957, 5.46554

这是此示例的可视化(每个人都可以得到一半的意大利辣香肠):

在此处输入图片说明

更多示例:

Input: 9 people, 1 pepperoni at: (0.03, 0.01)
Output: 0, 0.4065, 0.8222, 1.29988, 1.94749, 3.03869, 4.42503, 5.28428, 5.83985

在此处输入图片说明

Input: 5, (0.4, 0.3), (0.45, 0.43), (-0.5, -0.04)
Output: 0, 0.64751, 0.73928, 0.84206, 3.18997

在此处输入图片说明

计分

这是,因此最少要赢得字节数。


必须坚持多大的精确度才能将提交视为有效?
Rainbolt 2014年

@Rainbolt我想说4或5个小数位就足够了。你有什么建议?我应该将其添加到问题中。
kukac67 2014年

我不确定每个问题是否都可以解决。如果均匀间隔7片和3个意大利辣香肠怎么办?
弥敦道·美林

1
@NathanMerrill然后每个人都会得到3/7的意大利辣香肠。:)(切片的大小无关紧要。)
kukac67

1
披萨帽尝试失败。下次再问一个简单的问题。;)
Ilmari Karonen 2014年

Answers:


7

Mathematica,221个字节

f=(A=Pi.01Length@#2/#;l=m/.Solve[Norm[{a,b}-m{Cos@t,Sin@t}]==.1,m];k=(l/.{a->#,b->#2})&@@@#2;d=1.*^-5;For[Print[h=B=0];n=1,n<#,h+=d,(B+=If[Im@#<0,0,d(Max[#2,0]^2-Max[#,0]^2)/2])&@@@(k/.{t->h});If[B>A,n+=1;Print@h;B-=A]])&

取消高尔夫:

f = (
   A = Pi .01 Length@#2/#;
   l = m /. Solve[Norm[{a, b} - m {Cos@t, Sin@t}] == .1, m];
   k = (l /. {a -> #, b -> #2}) & @@@ #2;
   d = 1.*^-5;
   For[Print[h = B = 0]; n = 1, n < #, h += d,
    (
      B += If[Im@# < 0, 0, d (Max[#2, 0]^2 - Max[#, 0]^2)/2]
    ) & @@@ (k /. {t -> h});
    If[B > A, n += 1; Print@h; B -= A]
   ]
) &

这定义了一个函数,该函数将切片的数量和意大利辣味香肠坐标对的列表作为参数,例如

f[8, {{0.4, 0.2}, {-0.3, 0.1}, {-0.022, -0.5}, {0.3, -0.32}}]

它将遍历比萨饼时将切片打印到控制台。

在大多数披萨上,这是相当慢的,因为(为了达到所需的精度)我以1e-5的步长积分了从0到2π的意大利辣味香肠面积。要在合理的时间内获得不太精确的结果,可以1.*^-5将末尾更改为1.*^-3

怎么运行的

这个想法是将比萨饼切成薄片,同时将覆盖的意大利辣香肠片整合在一起。只要该区域达到每人需要的意大利辣香肠数量,我们就会报告当前角度并重置区域计数器。

要获得被冲走的意大利辣味香肠面积,我们将直线与意大利辣味香肠相交,以利用距原点的两条距离,即直线与意大利辣味香肠相交。由于一条线在两个方向上都延伸到无穷大,因此我们需要将这些距离限制为非负值。这解决了两个问题:

  • 对每个意大利辣味香肠的交叉点计数两次,一次为正,一次为负(实际上将产生0的总面积)。
  • 仅计算包含在原产地中的意大利辣味香肠楔块。

稍后将包括一些图表。


是的 这是我的进攻计划。至少我现在可以更轻松地举例说明!:D
kukac67 2014年

我注意到您的实现有时会输出一个额外的角度,这将创建一个没有意大利辣香肠的额外切片。(例如具有输入:[8, {{0.4, 0.2}, {-0.3, 0.1}, {-0.022, -0.5}, {0.3, -0.32}}]
kukac67

@ kukac67已修复。
Martin Ender 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.