安排四路停车


14

一排汽车在一个四向停车标志处排队等候前进。每个人都对下一步要走什么,谁要走什么方向等感到困惑。显然,次优。

您的工作是以最佳方式安排停车标志处的交通。

作为输入,您将收到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:您的第4步,EW,向东直行,向西转左。这不是允许的配置。
基思·兰德尔

@Fatalize:我有一个程序使用动态编程来完成。
基思·兰德尔

是的,对此感到抱歉。我的程序中有一个错误。我很快就会发布答案…
ESultanik

Answers:


3

Python,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
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.