寻找最大路径


12

给定一个正数的平方,自然数写一个程序,找到一条水平和垂直路径,沿着它们的数字总和最大。甲水平路径从第一列到最后去,并具有通过一个在每个步骤中,以增加其列位置。甲垂直路径从第一行进行到最后的,并具有由一个在每个步骤中,以增加其行位置。此外,水平路径中的行位置可以保持相同或沿任一方向改变一个,对于垂直路径也是如此。

为了说明这一点,以下可能是有效的路径:

有效路径的图示

以下路径将无效,因为它会向后退(并在某些地方保留在同一行):

无效路径的图示

以下路径同样无效,因为它一步一步将行位置更改了多个:

无效路径的另一种说明

注意:解决方案应在可接受的时间内运行。

输入值

在标准输入上给出n行输入,每行输入n个以空格分隔的正整数。2≤ Ñ ≤40的每一行是由一个换行符终止。数字足够小,以至于最大和适合32位有符号整数。

输出量

水平和垂直路径的最大和(按此顺序),以单个空格分隔。

样品输入1

1 2
1 2

样品输出1

3 4

样品输入2

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
2 1 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 4 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 4 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

样品输出2

37 35

样品输入3

683 671 420 311 800 936
815 816 123 142 19 831
715 588 622 491 95 166
885 126 262 900 393 898
701 618 956 865 199 537
226 116 313 822 661 214

样品输出3

4650 4799

为方便起见,我们在bash(感谢Ventero)和PowerShell中准备了一些测试用例,您可以通过它们运行程序。调用是:<test> <command line>,所以类似./test python paths.py./test.ps1 paths.exe。玩得开心 :-)


@Joey:与去年我们在比赛中使用的任务相比有轻微的改变:)
Joey

bash测试脚本+10 !我希望所有代码高尔夫都附带这样的东西。
MtnViewMark 2011年

@MtnViewMark:我们尝试:-)我个人讨厌发布后需要太多澄清的任务,而且我通常还是会编写自己的测试脚本,因为我需要知道高尔夫尝试何时会进一步引入回归。我还观察到有些人倾向于发布明显错误的答案。测试用例有助于使每个人都处于同一行。拥有一个可以处理每个任务的工具,而不是仅针对每个任务的一次性hackjob,显然会更好,但是我们还不足够;-)
Joey

Answers:


6

GolfScript-49个Nabb增强角色

51个字符,其中
50个是绝对必要的字符,另外3个是懒人,只完成了1个
56个主要是多余字符的工作

n%{~]}%.zip{{0@+\{\.1>\3<$-1=@+}%\;}*$-1=\}2*' '@

51解决方案:

n%{~]}%.zip{(\{0@+\{\.1>\3<$-1=@+}%\}%;$-1=\}2*' '@

53解决方案:

n/{~]}%);.zip{(\{0@+\{\.1>\3<$-1=@+}%\}%;$-1=\}2*' '@
             a8_b9___c10___11______12 13      14_

该方法一次作用于两行,一个包含每个点达到​​的最大和,而另一个包含下一行。

a / 14:重复两次,每个结果一次。
8:从输入中获取第一行,并将其切换到输入数组后面,这是第一组最大和。
b / 13:遍历数组中的每个其余行。
9:将0放在最大和的开头。
c / 12:遍历该行的每个元素。
10:在删除第一个元素的情况下,复制最大和。
11:取最大和的前3个元素,对它们进行排序,然后将最大的和添加到该行的当前元素中。

56解决方案:

n/{~]}%);.zip{1,99*\{{\.1>\3<$-1=@+}%0\+\}%;$-1=\}2*' '@
1________2___ 3____ 4______________________5_____ 6_7___

1:从输入到9个字符的数组,实际上只用1就可以完成,但是我弄破了那个键,所以必须这样做。
2:4个字符只是为了制作转置副本。
3:以5个字符组成99个0的数组,这可能以一种更聪明的方式完成,但是我抽了很多杂草来弄清楚该怎么做。
4:过于复杂的双循环,遍历输入的每个元素,并执行一些模糊逻辑或类似的操作来产生结果。Nabb可能会产生大约3½个字符的等效字符。
5:到现在为止,结果就在数组内部,那里就是这段愚蠢的代码,它可以将其取出(然后将剩下的残渣扔掉(并将结果放到适当的位置))。
6:此命令非常简单,以至于在最佳解决方案中其字符数可能为负。7:至此,程序确实完成了,但是由于前面代码中的草率性,输出的顺序错误并且缺少空格,因此这里要花很多时间。


啊,我只是不小心假设输入内容不以换行符结尾。令我惊讶的是它实际上部分起作用,这种东西通常会完全把GolfScript程序弄乱。
aaaaaaaaaaaa

1
看起来不错,尽管您应该使用{}*而不是(\{}%
Nabb

是的,这很有意义,谢谢。
aaaaaaaaaaaa

3

J,91 95

a=:".;._2(1!:1)3
c=:4 :'>./x+"1|:y,.(1|.!.0 y),._1|.!.0 y'
p=:[:>./c/
(":(p|:a),p a)1!:2(4)

我拒绝做IO,大大降低了我的分数。通过测试线束中的所有测试(尽管在输入以测试线束结尾时才有效)。

我删除了Windows行尾的处理,因为Chris建议不要这样做。多平台版本将a=:".;._2 toJ(1!:1)3作为第一行。

说明:

  • f通过正常调用p并输入转置(|:)给出解对。
  • p取每行()之间>./应用的行总数的最大值cc/
  • c占用两行(x和y)。它将x加到y的每一个中,y向上移动1个单元格(1|.!.0 y),y向下移动1个单元格(_1|.!.0 y)。然后,它取每一行三个选择的最大值。(>./)。其余的都是[原文]-我不确定我是否做得对。

4
确实,降低了您的分数。-1
aaaaaaaaaaaaa

@eBusiness:您确定否决权是对不完整解决方案的正确回应吗?
Jesse Millikan

1
@乔伊:不赞成是另一种选择。当时我太累了,无法做IO,但是我的解决方案与其他J解决方案有很大不同,因此我真的很想发布它。如果有一种明确的方式将答案标记为“不参与”,或类似的方式,我就会有。
Jesse Millikan

@Joey:另一个原因是,即使解决方案已解决,向下投票也不太可能被撤销;原始用户必须回来并更改投票。(已删除,意识到这会缩短讨论的时间,并且不删除内容。我想我会去拍摄“纪律”徽章。)
Jesse Millikan

@Jesse Millikan:我们做到了。没有任何保证,但是如果您在合理的时间内解决问题,大多数拒绝投票的人应该撤回他们的票。
aaaaaaaaaaaa

3

Haskell:314个必要字符

import Data.Vector(fromList,generate,(!))
import List
l=fromList
x=maximum
g=generate
p a=show$x[m!i!0|i<-[0..h-1]]where{
w=length$head a;h=length$a;n=l$map l a;
m=g h$ \i->g w$ \j->n!i!j+x[k#(j+1)|k<-[i-1..i+1]];
i#j|i<0||i>=h||j>=w=0|1>0=m!i!j;}
q a=p a++' ':(p.transpose)a
main=interact$q.map(map read.words).lines

注意:这需要模块Data.Vector。我不确定它是否包含在Haskell平台中。

非高尔夫版本:

import Data.Vector(fromList,generate,(!))
import Data.List

-- horizontal; we use transpose for the vertical case
max_path :: [[Integer]] -> Integer
max_path numbers = maximum [m ! i ! 0 | i <- [0..h-1]] where
    w = length (head numbers)
    h = length numbers
    n = fromList $ map fromList numbers
    m = generate h $ \i -> generate w $ \j ->
        n ! i ! j + maximum [f i' (j+1) | i' <- [i-1..i+1]]
    f i j | i < 0 || i >= h || j >= w = 0
    f i j = m ! i ! j

max_paths :: [[Integer]] -> String
max_paths numbers = (show . max_path) numbers ++ " " ++
                    (show . max_path . transpose) numbers

main = interact $ max_paths . map (map read . words) . lines

此解决方案结合使用懒惰和Data.Vector进行记忆。对于每个点,都会计算从它到末端的最大路径的解,然后将其存储在Vector的单元格中,m并在需要时重用。


我想如果将所有定义折叠到一行中,则可以在大括号中删除花括号。
FUZxxl

2

Ruby 1.9,155个字符

f=->t{(1...l=t.size).map{|a|l.times{|b|t[a][b]+=t[a-1][(b>0?b-1:0)..b+1].max}};t[-1].max};q=[*$<].map{|a|a.split.map &:to_i};puts [f[q.transpose],f[q]]*" ""

通过所有测试用例的简单解决方案。


2

Haskell,154个字符

import List
z=zipWith
f=show.maximum.foldl1(\a->z(+)$z max(tail a++[0])$z max(0:a)a)
q a=f(transpose a)++' ':f a
main=interact$q.map(map read.words).lines

  • 编辑:(155-> 154)内联折叠的函数

使用会zipWith3缩短代码吗?
骄傲的haskeller 2014年

我认为您可以将foldl1 maxmax 替换为,这会添加字符,但允许您排除foldl1和max,这应该节省字符。
骄傲的haskeller 2014年

maximum.foldl1maxmax--vs-- f=foldl1;m=max;f m.fm,和m。-或20比22。所以,不,它不会保存。
MtnViewMark 2014年

对。我只是记得单态性限制将停止写作m=max。zipWith3呢?
自豪的haskeller 2014年

1

J,109 + 10 = 119个字符

y=:0".(1!:1)3
N=:%:#y
y=:y$~N,N
r=:(((1&{)(+(3>./\0,0,~]))(0&{)),2&}.)^:(<:N)
(":([:>./"1([:r|:),r)y)(1!:2)4

运行tr

cat << EOF | tr \\n ' ' | ./maxpath.ijs

和J中一样,大多数代码用于输入/输出。“实际”代码为65个字符:

r=:(((1&{)(+(3>./\0,0,~]))(0&{)),2&}.)^:(<:#y)
([:>./"1([:r|:),r)y

通过所有测试用例


因此,我们需要再次使用JB并将其解析减少到10个字符的解决方案吗?;-)
Joey

@Joey我在度假,我几乎没有互联网可以访问;没有太多时间打高尔夫球;-)
JB

您能提示我如何直接运行maxpath.ijs吗?
杰西·米利坎

@Jesse:在* nix中,将一些#!/usr/bin/env jconsole文件放在文件顶部并设置可执行标志。
Eelvex 2011年

1

蟒蛇,149

import sys
def f(g,t=[]):
 for r in g:t=[int(e)+max(t[i-1:i+2]+[0])for i,e in enumerate(r)]
 print max(t),
g=map(str.split,sys.stdin)
f(zip(*g)),f(g)

如果仅计算垂直或水平最短路径,
则可以就地完成,节省大约三分之一的字节。


1

Python,204个字符

import sys
I=sys.stdin.read()
n=I.count('\n')
A=map(int,I.split())
R=range(n)
X=lambda h,a:[a[i]+max(([0]+h)[i:i+3])for i in R]
h=v=[0]*n
for i in R:h=X(h,A[i*n:i*n+n]);v=X(v,A[i::n])
print max(v),max(h)
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.