4 방향 정지 일정


14

진행을 기다리는 4 방향 정지 표지판에 많은 차량이 줄 지어 있습니다. 누가 다음에 갈 것인지, 누가 어떤 식으로 갈 것인지 등에 대해 혼란스러워합니다. 분명히 차선책입니다.

당신의 임무는 최적의 방식으로 정지 신호에서 트래픽을 예약하는 것입니다.

4 개의 기본 방향 각각에 대해 4 개의 문자열 요청을 입력으로받습니다. 각 요청은 L왼쪽, S직선 또는 R오른쪽입니다.

LLSLRLS
SSSRRSRLLR
LLRLSR
RRRLLLL

첫 번째 행은 교차로의 북쪽 입구에있는 라인업입니다. 첫 번째 줄의 자동차는 좌회전 (동쪽 출구)합니다. 다음 행은 들어오는 동쪽, 남쪽 및 서쪽 입구입니다. 따라서 서쪽에서 오는 첫 번째 차는 남쪽으로 나가기를 원합니다.

트래픽은 일련의 단계로 이동합니다. 각 단계에서 진행하려면 라인 헤드에서 자동차의 하위 세트를 선택해야합니다. 선택한 차량 이 서로 간섭 해서는 안됩니다 . 두 대의 자동차가 같은 방향을 벗어나거나 서로의 경로를 넘어야하는 경우 방해를받습니다 (표준 오른 손잡이 운전 규칙). 따라서 똑바로 가고 싶은 두 대향 차량이 같은 단계를 밟을 수 있습니다. 4 대의 자동차가 모두 우회전하기를 원할 수 있습니다. 두 대향 차량이 동시에 왼쪽으로 회전 할 수 있습니다.

귀하의 임무는 최소 일련의 단계로 교차로를 예약하는 것입니다. 각 단계마다 들어오는 차량의 나침반 방향이 나열된 라인을 출력하십시오. 위의 예에서 최소 스케줄은 14 단계입니다. 최소한의 일정은 다음과 같습니다.

N    [L from North]
E    [S from East]
E    [S from East]
E    [S from East]
NESW [L from North, R from East, L from South, R from West]
NE   [S from North]
EW   [R from East]
NESW [L from North, R from East, L from South, R from West]
W    [L from West]
EW   [L from East, L from West]
NESW [R from North, L from East, R from South, L from West]
NES  [L from North, R from East, L from West]
NS   [S from North, S from South]
SW   [R from South, L from West]

프로그램은 1 분 안에 각 라인에서 50 대의 차량을 처리 할 수 ​​있어야합니다. 4 개의 문자열을 입력하고 일정을 출력하는 것은 언어에 편리한 방법 일 수 있습니다.

최단 프로그램이 이깁니다.

더 큰 예 :

RRLLSSRLSLLSSLRSLR
RLSLRLSLSSRLRLRRLLSSRLR
RLSLRLRRLSSLSLLRLSSL
LLLRRRSSRSLRSSSSLLRRRR

최소 38 발이 필요합니다. 하나의 가능한 해결책 :

E
EW
E
ESW
S
NS
ES
NESW
NSW
ESW
ES
NSW
NS
NS
NW
EW
NSW
NS
EW
NES
EW
NSW
NE
E
NE
EW
E
E
EW
EW
EW
W
ESW
NSW
NSW
NS
NSW
NEW


첫 번째 예의 최소 일정을 어떻게 계산 했습니까? 저는 이것이 유효한 13 단계 일정이라고 생각합니다 : NSW, NSW, ESW, EW, EW, NES, NE, EW, NE, NEW, NS, ES, E
ESultanik

@ESultanik : 네 번째 단계 인 EW가 동쪽으로 직진하고 서쪽으로 좌회전합니다. 허용 된 구성이 아닙니다.
Keith Randall

@ Fatalize : 동적 프로그래밍을 사용하는 프로그램이 있습니다.
Keith Randall

아, 죄송합니다. 프로그램에 버그가있었습니다. 곧 답변을 드리겠습니다…
ESultanik

답변:


3

파이썬, 1219 바이트

나는 골프를 타는 데 많은 시간과 노력을 들이지 않았지만 다른 답변이 나오기 시작하면 그것을 향상시킬 수 있습니다. 내가 사용하는 A * 검색을 으로 허용 발견 최적을 보장. 휴리스틱도 일관성 이 있음을 확신합니다 (확인하지 않아도 ). 이는 O (동적 프로그래밍) 임을 의미합니다 .

프로그램은 사용자가 지정한 형식으로 STDIN에서 네 줄로 읽고 결과를 지정한 형식으로 STDOUT에 인쇄합니다.

from heapq import heappush,heappop
from itertools import combinations
N,E,S,W=range(4)
L="L"
R="R"
T="S"
d=[{L:E,R:W,T:S},{L:S,R:N,T:W},{L:W,R:E,T:N},{L:N,R:S,T:E}]
b=set([(N,S,W,E),(N,S,E,W),(S,N,W,E),(S,N,E,W),(E,W,N,E),(N,S,W,N),(S,N,E,S),(W,E,S,W)])
for x in list(b):b.add(x[2:]+x[:2])
def v(*a):return a[1]!=a[3] and a not in b
i=lambda:raw_input()+'\n'
i=map(lambda l:map(lambda e:("NESW"[l[0]],d[l[0]][e]), l[1]),enumerate((i()+i()+i()+i()).split()))
q=[]
heappush(q,(0,[],i))
while q:
    h,a,n=heappop(q)
    m=sum(map(bool,n))
    if m==0:
        print "\n".join(a)
        break
    for r in range(4,0,-1):
        f=False
        for c in combinations(range(4),r):
            l=True
            for i in c:
                if not n[i]:
                    l=False
                    break
            if not l:continue
            l=True
            for x,y in combinations(c,2):
                if not v(x,n[x][0][1],y,n[y][0][1]):
                    l = False
                    break
            if l==False:continue
            f=True
            e=list(n)
            for i in c:e[i]=e[i][1:]
            heappush(q,(m-r+min(map(len,e)),a+["".join([n[x][0][0] for x in c])],e))
        if f:break

사용법 예 :

$ time echo "RRLLSSRLSLLSSLRSLR\nRLSLRLSLSSRLRLRRLLSSRLR\nRLSLRLRRLSSLSLLRLSSL\nLLLRRRSSRSLRSSSSLLRRRR" | python 4way.py
NES
NEW
NSW
NS
NS
ESW
NS
NES
NEW
NS
NES
NSW
NS
NS
NSW
NW
NS
NS
NS
EW
ES
SW
EW
EW
SW
ES
EW
EW
EW
EW
E
EW
EW
EW
EW
EW
E
EW
echo   0.00s user 0.00s system 38% cpu 0.002 total
python 4way.py  0.02s user 0.01s system 90% cpu 0.030 total
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.