填满湖泊,二维


22

这个问题一维版本非常简单,因此这是一个更难的2D版本。

在标准输入上为您提供了2D的陆地高度阵列,您必须弄清楚下雨时湖泊的形成位置。高度图只是数字0-9(含)的矩形数组。

8888888888
5664303498
6485322898
5675373666
7875555787

您必须输出相同的数组,并用将所有在水下的位置替换*

8888888888
566*****98
6*85***898
5675*7*666
7875555787

水可以沿对角线逸出,因此在这种配置下不会有湖泊:

888
838
388

最短的代码胜出。您的代码必须处理最大80宽和24高的尺寸。

另外三个例子:

77777    77777
75657    7*6*7
75757 => 7*7*7
77677    77677
77477    77477

599999    599999
933339    9****9
936639 => 9*66*9
935539    9*55*9
932109    9****9
999999    999999

88888888    88888888
84482288    8**8**88
84452233 => 8**5**33
84482288    8**8**88
88888888    88888888

4
如果可能的话,再使用一些测试用例会更好(特别是输入时,您将考虑边缘用例)。

输出行中是否允许尾随空格?
hallvabo,2012年

@hallvabo:不。你为什么要
基思·兰德尔

Keith:我有另一个解决方案,我将输入行填充到固定宽度,并在算法中保存了一些字节。如果必须删除输出的填充,则此方法比当前最佳解决方案占用更多字节。
hallvabo,2012年

Answers:


7

Haskell,258个字符

a§b|a<b='*'|1<3=a
z=[-1..1]
l m=zipWith(§)m$(iterate(b.q)$b(\_ _->'9'))!!(w*h)where
 w=length m`div`h
 h=length$lines m
 q d i=max$minimum[d!!(i+x+w*y)|x<-z,y<-z]
 b f=zipWith(\n->n`divMod`w¶f n)[0..]m
 (j,i)¶g|0<i&&i<w-2&&0<j&&j<h-1=g|1<3=id
main=interact l

示例运行:

$> runhaskell 2638-Lakes2D.hs <<TEST
> 8888888888
> 5664303498
> 6485322898
> 5675373666
> 7875555787
> TEST
8888888888
566*****98
6*85***898
5675*7*666
7875555787

通过所有单元测试。大小没有任意限制。


  • 编辑(281→258):不测试稳定性,仅迭代到上限;停止传递常量参数m

5

Python中,483 491个字符

a=dict()
def s(n,x,y,R):
 R.add((x,y))
 r=range(-1,2)
 m=set([(x+i,y+j)for i in r for j in r if(i,j)!=(0,0)and(x+i,y+j)not in R])
 z=m-set(a.keys())
 if len(z)>0:return 1
 else:return sum(s(n,k[0],k[1],R)for k in[d for d in m-z if a[(d[0],d[1])]<=n])
i=[list(x)for x in input().strip().split('\n')]
h=len(i)
w=len(i[0])
e=range(0,w)
j=range(0,h)
for c in[(x,y)for x in e for y in j]:a[c]=int(i[c[1]][c[0]])
for y in j:print(''.join([('*',str(a[(x,y)]))[s(a[(x,y)],x,y,set())>0] for x in e]))

我很确定有一种更好(更短)的方法


大多是工作,但我也需要更换input()sys.stdin.read()和删除尾随\n从我的样本输入。
基思·兰德尔

@Keith Randall- sys.stdin.read()从文件中读取对吗?我在Python上还很新。
系统停机时间

sys.stdin.read()读取STanDard输入,直到EOF。 input()读取并评估一行标准输入。
基思·兰德尔

4

Python中,478 471个字符

(不包括注释 。452450个字符不包括导入。)

import sys,itertools
i=[list(x)for x in sys.stdin.read().strip().split('\n')]
h=len(i)
w=len(i[0])
n=h*w
b=n+1
e=range(h)
d=range(w)
# j is, at first, the adjancency matrix of the graph.
# The last vertex in j is the "drain" vertex.
j=[[[b,1][(t-r)**2+(v-c)**2<=1 and i[r][c]>=i[t][v]] for t in e for v in d]+[[b,1][max([r==0,r>h-2,c==0,c>w-2])]]for r in e for c in d]+[[0]*b]
r=range(b)
for k,l,m in itertools.product(r,repeat=3):
    # This is the Floyd-Warshall algorithm
    if j[l][k]+j[k][m]<j[l][m]:
        j[l][m]=j[l][k]+j[k][m]
# j is now the distance matrix for the graph.
for k in r:
    if j[k][-1]>n:
        # This means that vertex k is not connected to the "drain" vertex, and is therefore flooded.
        i[k/w][k-w*(k/w)]='*'
for r in e:print(''.join(i[r]))

这里的想法是,我构造一个有向图,其中每个网格单元都有其自己的顶点(加上一个附加的“漏极”顶点)。在图中,从每个较高值的单元格到其相邻的较低值的单元格都有一条边,此外,从所有外部单元格到“排水”顶点都有一条边。然后,我使用Floyd-Warshall来计算将哪些顶点连接到“漏极”顶点;连接的所有顶点将被淹没并绘制一个星号。

我在浓缩Python代码方面没有太多经验,因此我可能可以采用更简洁的方法来实现此方法。


3

常见的Lisp,833

(defun drains (terr dm a b)
  (cond
    ((= (aref dm a b) 1) t)
    ((= (aref dm a b) -1) nil)
    ((or (= a 0) (= b 0)
     (= a (1- (array-dimension terr 0)))
     (= b (1- (array-dimension terr 1)))) t)
    (t (loop for x from -1 to 1
       do (loop for y from 0 to 1
           do (if (and (or (> x 0) (> y 0))
                   (drains terr dm (+ a x) (+ b y))
                   (<= (aref terr (+ a x) (+ b y))
                   (aref terr a b)))
              (progn
                (setf (aref dm a b) 1)
                (return-from drains t)))))
    (setf (aref dm a b) -1)
    nil)))

(defun doit (terr)
  (let ((dm (make-array (array-dimensions terr))))
    (loop for x from 0 to (- (array-dimension terr 0) 1)
       do (loop for y from 0 to (- (array-dimension terr 1) 1)
         do (format t "~a"
            (if (drains terr dm x y)
                (aref terr x y)
                "*"))
         finally (format t "~%")))))

没有尝试打高尔夫球,我只是发现这个问题很有趣。输入是地图的2D数组。该解决方案检查每个正方形,看是否“变色”-如果正方形在外部边缘上或者与排水的等高或更低高度正方形相邻,则正方形会消失。为了避免无限循环,该代码保留了一个“排水图”(dm),其中存储了已确定的正方形的排水状态。


您所描述的逻辑不太正确,因为它无法正确处理孤岛的情况。
基思·兰德尔

1

Python,246个字符

import os
a=list(os.read(0,2e3))
w=a.index('\n')+1
a+=' '*w
def f(p,t):
    if e<a[p]or p in t:return
    t[p]=1
    return'*'>a[p]or any(f(p+d,t)for d in(~w,-w,-w+1,-1,1,w-1,w,w+1))
z=0
for e in a:
    if(' '<e)*~-f(z,{}):a[z]='*'
    z+=1
print''.join(a[:~w])

该解决方案通过在每个位置执行DFS来确定是否填充来工作。

如果在每行上允许尾随空格,则可以通过使用w = 80并将输入行的空格填充到80个字符来缩短它。

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.