建立铁轨并欺骗政府


30

您是19世纪美国的铁路企业家,火车之所以流行,是因为火车是陆上运输大量物料的最有效手段。从东部沿海到西部一些最近被殖民的土地,全国都需要铁轨。

为了满足这种需求,美国政府将征收税款以补贴铁路。他们答应为铺设的每一英里轨道向您的铁路公司付款。由于在丘陵和山区铺设铁轨比在平坦的土地上铺设铁轨更昂贵,因此它们会相应地调整其用量。也就是说,政府将支付

  • 在平坦土地上铺设的每英里轨道5,000美元
  • 在丘陵地带铺设的每英里航迹为$ 12,500
  • 每英里在山上铺设的路线20,000美元。

当然,该计划不能准确反映铺设轨道的实际成本。

您已经雇用了一些制图师来绘制您将要分析高程的区域的地形图。这是一张这样的地图:

S12321
121234
348E96

每个数字代表一平方英里的土地。S是起点,E是终点。每个数字代表该区域中海拔变化的强度。

  • 编号为1-3的土地构成平地。
  • 编号为4-6的土地构成丘陵地。
  • 编号为7-9的土地构成山脉。

通过多年的铁轨建设经验,您已经评估出铁路建设成本(以美元为单位)满足以下公式:

Cost_Per_Mile = 5000 + (1500 * (Elevation_Rating - 1))

这意味着在某些海拔梯度上修建房屋将比政府给您更多的钱,有时它会有利可图,有时您甚至会收支平衡。

例如,在海拔3的坡度上行驶一英里需要花费8,000美元,但是您只得到5,000美元的报酬,因此损失了3000美元。相比之下,在海拔高度为7的位置上建立一英里的轨道需要花费$ 14,000,但是您却获得了$ 20,000的收益:获利$ 6,000!

这是示例地图以及两个不同的可能路径。

S29    S#9    S##
134    1#4    1##
28E    2#E    2#E

第一条轨道的建造成本为30,000美元,但政府会为您支付30,000美元。您不会从此轨道中获利。

另一方面,第二台的建造成本为56,500美元,但您会得到62,500美元的报酬。您从此轨道中获利$ 6,000。

您的目标:给出一个浮雕图,找到从头到尾最有利可图(或也许仅仅是最便宜)的路径。如果有多个路径绑定,则其中任何一个都是可接受的解决方案。

计划详情

文本输入由矩形的数字和一个起点和终点分隔。每个数字都是1到9之间的一个整数(包括1和9)。除此之外,可以在合理的范围内根据需要提供输入。

输出应采用与输入相同的格式,其中已将构建轨道的数字替换为哈希(#)。由于某些反复无常的政治家施加了任意规定,因此轨道只能沿水平或垂直路径行驶。换句话说,您不能回溯或对角线走。

对于最多6行和6列的地图,该程序应能够在合理的时间内(即<10分钟)求解。

这是一场代码高尔夫挑战赛,因此最短的程序胜出。

我有一个示例(非高尔夫)实现

样品I / O

S12321
121234
348E96

S12321
######
3##E##



S73891
121234
348453
231654
97856E

S#3###
1###3#
3#####
######
#####E

如果输出不明确,那是什么?
FUZxxl

2
输出可能是不明确的,但无论您如何追踪,其利润都是相同的。
彼得·奥尔森

我认为有一个小错误。应4134在例如地图是6
JiminP 2011年

@JiminP是的,这是一个地方更改数字而不是另一个地方的错误。现在应该修复。
彼得·奥尔森

3
三年后,政府四处张望,开始怀疑为什么所有的山丘都被铁轨覆盖。但是,嘿,当地政府的用户在政府的资助下获得了一个不错的过山车/旅游车,这是免费的,这使人们更加幸福,那为什么还要关心呢?(*除一些6级山丘之外)
约翰·德沃夏克

Answers:


5

Python,307个字符

import os
I=os.read(0,99)
n=I.find('\n')+1
I='\0'*n+I+'\0'*n
def P(p):
 S=[]
 for d in(-n,-1,1,n):
  y=p[-1]+d
  if'E'==I[y]:S+=[(sum((int(I[v])-1)/3*75-15*int(I[v])+15for v in p[1:]),p)]
  if'0'<I[y]<':'and y not in p:S+=P(p+[y])
 return S
for i in max(P([I.find('S')]))[1][1:]:I=I[:i]+'#'+I[i+1:]
print I,

P采取部分路径,p并返回将其延伸到的所有方式E。每个返回的路径都与其分数配对,因此max可以找到最佳路径。

在6x6地图上耗时约80秒。


1
您可以使用制表符替换缩进的第二级,以节省3个字符
gnibbler

4

Python的:529个 482 460字节

我的解决方案不会赢得任何奖励。但是,由于仅发布了两个解决方案,并且我发现了这个问题很有趣,所以我还是决定发布我的答案。

编辑:感谢霍华德的建议。我设法剃了很多钱!

import sys
N=len
def S(m,c,p=0):
 if m[c]=='E':return m,p
 if m[c]<'S':
    b=list(m);b[c]='#';m=''.join(b)
 b=[],-float('inf')
 for z in(1,-1,w,-w):
    n=c+z
    if 0<=n<N(m)and m[n]not in('S','#')and(-2<z<2)^(n/w!=c/w):
     r=S(m,n,p+(0if m[n]=='E'else(int(m[n])-1)/3*5-int(m[n])+1))
     if b[1]<r[1]:b=r
 return b
m=''
while 1:
 l=sys.stdin.readline().strip()
 if l=='':break
 w=N(l);m+=l
b,_=S(m,m.index('S'))
for i in range(0,N(b),w):print b[i:i+w]

就是这样开始的。:)
乔纳森·范·马特雷2014年

1
一些小的改进:P并且M每次仅使用一次,因此内联然后是一个好主意(对于单个调用,有时几乎在所有情况下都可以使用两次)。m[c]!='S'可以缩短到m[c]<'S',也abs(z)==1abs(z)<2甚至-2<z<2
2014年

您的“较小改进”为我节省了47个字节。我正在编辑我的答案。
sadakatsu 2014年

3

Ruby,233个字符

R=->s{o=s=~/S/m
s=~/E/m?(q=[-1,1,-N,N].map{|t|s[f=o+t]>'0'?(n=s*1
n[o]='#'
n[f]='S'
a=R[n]
a&&[a[0]-(e=s[f].to_i-1)/3*5+e,a[1]]):nil}-[nil]
q.sort!&&q[0]):[0,(n=s*1;n[o]='E'
n[$_=~/S/m]='S'
n)]}
N=1+(gets(nil)=~/$/)
$><<R[$_+$/*N][1]

一种Ruby蛮力方法,可以在6x6板上的时间限制内很好地运行。输入必须在STD​​IN上给出。

例子:

S12321
121234
348E96

S#2321
1#####
3##E##    
--    
S73891
121234
348453
231654
97856E

S#####
1212##
#####3
#3####
#####E

@PeterOlson我试图让您的挑战至少引起一点注意;-)
霍华德
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.