订购40条


15

我们有40条相同宽度但不同高度的棍棒。有多少种布置可以将它们彼此相邻放置,以便当我们从右边看时看到10条,而当我们从左边看时又看到10条?

例如,这样的排序是:订购示例

黑棒是隐藏的,红色棒是从左看时可以看到的棒,蓝色棒是从右眼看时可以看到的棒,紫色的棒(即最长的棒)是可以看到的棒从双方。

作为测试用例:

  • 如果我们有3个棍棒,那么从左边看2个,从右边看2个的订购数量是2
  • 如果我们有5个棍棒,那么从左边看3个,从右边看3个的订购数量是6
  • 如果我们有10个棍棒,那么从左边看4个从右边看4个的订购数量是90720

13
您可能希望避免使用固定输出的问题,因为最佳代码高尔夫球答案可能只会打印结果而不进行计算。我建议让这个问题有几个变量输入,例如N个摇杆,这样您就可以从左/右看到其中的K个,其中N和K是输入整数
Sp3000,2015年

4
如果您确实更改了规范,以使程序可以接受输入(我不明白为什么不这样做-您已经有了测试用例),则可能要考虑是否要对程序设置时间限制。
Sp3000

1
“必须使用您发布的程序来计算40/10的情况”应该是一个足够好的时间限制。
2015年

1
我无法克服10!/40 = 90720……是巧合的事实吗?
蒂姆(Tim)

1
@Tim 90720的意义是什么?Los Alamitos,CA的邮政编码?
Digital Trauma 2015年

Answers:


8

PARI / GP,80

f(n,v)=abs(sum(k=1,n-1,binomial(n-1,k)*stirling(k,v-1,1)*stirling(n-k-1,v-1,1)))

在铅笔/网格游戏之后,可见的杆数也称为“ 摩天大楼编号”。该代码基于OEIS A218531中的公式(仅稍有更改)。我对PARI的了解不多,但是我真的不认为这里有很多高尔夫运动。

测试用例全部显示在ideone.com上。结果为f(40,10)

192999500979320621703647808413866514749680

1
该公式有一个很好的理由。v左手摇杆的排列数为斯特林数s(n,v)。如果最高的摇杆位于位置k,则左眼的摇杆为该摇杆,并且左眼的摇杆在k-1position 左边的值左侧的子排列中k。因此,要拥有v左眼棒和v右眼棒,则可以s(k,v-1)选择左半边的s(n-k-1,v-1)排列,右半边的排列,以及binomial(n-1,k)将木棍分成两半的选择。
xnor

@xnor他们基本上在链接的PDF中给出了这种解释,但您的IMO措辞要好得多。
Geobits,2015年

您可以保存11个字节:f(n,v,s=stirling)=abs(sum(k=1,n--,binomial(n,k)*s(k,v-1)*s(n-k,v-1)))。这将保存sterling到一个变量以供重用,由于最后一个参数是1,所以将其最后一个参数保留下来,并从n中减去1而不是3次。
查尔斯

1

Python 3,259个字节

对此不是很满意。

import itertools as i
x=input().split()
y,k=x
y=int(y)
c=0
x=list(i.permutations(list(range(1,y+1))))
for s in x:
 t=d=0;l=s[::-1]
 for i in range(y):
  if max(s[:i+1])==s[i]:t+=1
 for i in range(y):
  if max(l[:i+1])==l[i]:d+=1
 if t==d==int(k):c+=1
print(c)

输入和输出示例:

10 4
90720

它生成所提供范围的所有可能组合,然后循环遍历它们,检查其中的每个数字以查看其是否等于先前数字的最大值。然后,它向后进行相同的操作,如果向前计数(t)=向后计数(d)=给定的视图编号(k),则它是有效的。它将其添加到计数器(c)并最后打印。


0

R,104

function(N,K)sum(sapply(combinat::permn(N),function(x)(z=function(i)sum(cummax(i)==i)==K)(x)&z(rev(x))))

去高尔夫球了一下:

    function(N,K) {
      all_perm <- combinat::permn(N)
      can_see_K_from_left <- function(i)sum(cummax(i) == i) == K
      can_see_K_from_both <- function(x)can_see_K_from_left(x) &
                                        can_see_K_from_left(rev(x))
      return(sum(sapply(all_perm, can_see_K_from_both)))
    }

0

Pyth- 38 36字节

基本上是R答案的端口。相当慢,甚至无法10, 4在线完成。

AGHQLlfqhS<bhT@bTUGlf!-,yTy_TH.pr1hG

Pyth唯一没有的是cummax和==over向量,但是这些仅花费了几个字节即可实现。

即将进行解释和进一步打高尔夫球。

在线尝试一下

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.