최대 경로 찾기


12

양의 제곱이 주어지면 자연수는 프로그램에 따라 숫자의 합이 최대 인 수평 및 수직 경로를 찾습니다. 수평 경로 마지막으로 첫 번째 열에서 이동하고 각 단계에서 하나의 열 위치를 증가한다. 수직 경로 첫 행부터 마지막까지 이동하고 각 단계에서 하나의 행 위치를 증가한다. 또한, 수평 경로 에서의 행 위치는 수직 경로와 마찬가지로 동일하게 유지되거나 어느 한 방향으로 하나씩 변경 될 수있다.

설명하기 위해 다음은 유효한 경로 일 수 있습니다.

유효한 경로의 그림

다음 경로는 뒤로 이동하므로 일부 위치에서 동일한 행에 남아 있기 때문에 유효하지 않습니다.

유효하지 않은 경로의 그림

다음 경로는 단일 단계에서 둘 이상의 행 위치를 변경하므로 동일하게 유효하지 않습니다.

유효하지 않은 경로의 또 다른 예

참고 : 솔루션은 적절한 시간 내에 실행해야합니다.

입력

N 과 입력 라인 N 개의 공간 분리 된 양의 정수 각 표준 입력에 주어진다. 2 ≤ n ≤ 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 2

@MtnViewMark : 우리는 시도 :-) 개인적으로 게시 후 너무 많은 설명이 필요한 작업을 싫어하고 골프를 시도하면 회귀가 추가로 발생하는 시점을 알아야하기 때문에 일반적으로 자체 테스트 스크립트를 작성합니다. 또한 일부 사람들은 명백하게 잘못된 답변을 게시하는 경향이 있음을 관찰했습니다. 테스트 사례는 모든 사람이 같은 줄을 타도록 도와줍니다. 각 작업마다 단 한 번의 해킹 작업 대신 모든 작업을 수행 할 수있는 시설을 갖추는 것이 더 나을 것입니다. 그러나 우리는 아직 멀지 않습니다 ;-)
Joey

답변:


6

GolfScript-49 Nabb 고급 캐릭터

51 자
(50) 엄격하고 완전하게 필요한 문자 만 1 일 개 한 + 3 게으름 뱅이
(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를 거부하고 점수를 크게 낮 춥니 다. 테스트 하니스의 모든 테스트를 통과합니다 (테스트 하니스에서 와 같이 입력이 줄 끝으로 끝나는 경우 에만 작동 함).

Chris가 필요하지 않다고 제안했기 때문에 Windows 줄 끝 처리를 제거했습니다. 멀티 플랫폼 버전은 a=:".;._2 toJ(1!:1)3첫 번째 라인이됩니다.

설명:

  • fp를 정상적으로 호출하고 입력을 바꿈으로써 솔루션 쌍을 제공합니다 ( |:).
  • p각 행 ( ) 사이에 >./적용 되는 최대 행 합계 ( )를 가져옵니다.cc/
  • c두 개의 행 (x 및 y)을 사용합니다. 그것은 각각의 y에 x를 더하고, y는 1 셀 위로 이동하고 ( 1|.!.0 yy _1|.!.0 y) 1 셀 아래로 이동합니다 ( ). 그런 다음 각 행에 대해 세 가지 대안 중 최대 값을 사용합니다. ( >./). 나머지는 순위 [sic]입니다-제대로하고 있는지 잘 모르겠습니다.

4
정확하게 점수를 낮추십시오. -1
aaaaaaaaaaaa

@eBusiness : 다운 보팅이 불완전한 솔루션에 대한 올바른 대응이라고 확신하십니까?
Jesse Millikan

1
@Joey : 비공개는 다른 옵션입니다. 당시 IO를 사용하기에는 너무 피곤했지만 솔루션은 다른 J 솔루션과 너무 다르므로 실제로 게시하고 싶었습니다. 답변을 "비 참여"또는 이와 유사한 것으로 표시 할 수있는 명시적인 방법이 있다면 그럴 것입니다.
Jesse Millikan

@Joey : 또 다른 이유는 솔루션이 고정 된 경우에도 다운 투표가 취소 될 가능성이 없다는 것입니다. 원래 사용자는 다시 와서 투표를 변경해야합니다. (삭제, 토론이 단락되고 삭제되지 않음을 알았습니다. 대신 "징계 됨"배지를 쏠 것 같습니다.
Jesse Millikan

@Jesse Millikan : 우리는 그렇게합니다. 보장 할 수는 없지만 합리적인 시간 내에 문제를 해결하면 대부분의 다운 보더는 투표를 취소해야합니다.
aaaaaaaaaaaa

3

하스켈 : 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 모듈이 필요합니다 . 그것이 하스켈 플랫폼에 포함되어 있는지 확실하지 않습니다.

언 골프 버전 :

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필요할 때 재사용됩니다.


모든 정의를 한 줄로 축소하면 where 문 뒤에 중괄호를 제거 할 수 있습니다.
FUZxxl

2

루비 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

하스켈, 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

나는 최대 값을로 바꿀 수 있다고 생각합니다.이 foldl1 max문자를 추가하지만 foldl1과 max를 제외하고 문자를 저장해야합니다.
자랑스런 Haskeller

maximum.foldl1, maxmax--vs-- f=foldl1;m=max;, f m.f, m,와 m. -또는 20 대 22. 아니, 그것은 저장되지 않습니다.
MtnViewMark

권리. 그리고 나는 단형 제한이 글쓰기를 멈출 것이라는 것을 기억했다 m=max. zipWith3은 어떻습니까?
자부심을 가진 haskeller

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

모든 테스트 사례를 통과


파싱을 10 자로 줄이는 솔루션으로 JB가 다시 필요합니까? ;-)
Joey

@Joey 나는 휴가 중이다, 나는 거의 인터넷에 접속할 수 없다; 골프를위한 시간이 많지 않다 ;-)
JB

maxpath.ijs를 직접 실행하는 방법을 알려줄 수 있습니까?
Jesse Millikan

@Jesse : * nix #!/usr/bin/env jconsole에서 파일 위에 일부 를 놓고 실행 가능 플래그를 설정하십시오.
Eelvex

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)

수직 또는 수평 최단 경로 만 계산하는 경우
대신 바이트의 3 분의 1을 절약하여 대신 수행 할 수 있습니다.


1

파이썬, 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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.