编程杯叠机器人


36

我敢肯定,每个人都可以看到杯子可以堆成金字塔(和其他形状)之前:

           A    
        A A A   
 A     A A A A  
A A A A A A A A

是的,A绝对足够代表杯子。

可以在地面上,结构右侧或两个相邻杯子的顶部添加新杯子。这是上面的结构,但是新杯子的所有可用位置都标有_

         _ A         
        A A A        
 A _ _ A A A A       
A A A A A A A A _ _ _

假设我们要建立一个可以组装这些杯子叠的机器人。机器人将了解两条简单的指令来操纵这种结构:

  • a:按照从左到右的阅读顺序在第一个可用位置添加一个新杯子(即,从上到下,从左到右扫描行,直到找到可用的位置,然后将杯子放在那里)。上面的示例将变为:

             A A   
            A A A  
     A     A A A A 
    A A A A A A A A
    
  • r:按照从左到右的顺序卸下第一个杯子。上面的示例将变为:

            A A A  
     A     A A A A 
    A A A A A A A A
    

事实证明,仅使用这两个操作就可以从头开始构建任何结构。例如

      A
 A   A A
A A A A A

可以按照指令顺序构建

aaaaaaaaaaaarrrrraa

可以使用以下示例构建以上较大的示例

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaarrrrrrrrrrrrrrrrrraaaaaaarr

这是更大的一个:

    A
   A A                   A
  A A A     A   A       A A
 A A A A   A A A A     A A A A
A A A A A A A A A A   A A A A A

可以用

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrraaaaaaaaaaaaaaaaaaarrrrrrrrrrrrrrraaaaaaaaaaaaaarrrrrrrrrrraaaaaaaa

注意:如果按照拆卸说明释放了地面上的斑点,将杯子放置在所有现有杯子的右侧之前,它们将被重新使用。例如

aaaarrra

将产生

A   A

    A A

您可以将地面想象成一排无限长的杯子。

挑战

给定堆叠杯的结构,返回代表构建此结构的说明的序列。您的主要分数是底部提供的测试用例的说明总数。如果出现平局(很可能是这样,因为我确信有效的最佳解决方案是可能的),则以最短的解决方案为准。

以下是有关规则的更多详细信息:

  • 您可能假设输入的底行没有前导空格,因此始终使用杯子的最左侧接地点。
  • 您可以假定任何合理数量的尾随空格(没有空格,一个空格,填充为矩形,填充为具有单个尾随空格的矩形)。
  • 您可以有选择地期望输入以单个尾随换行符结尾。
  • 您可以选择任意两个不同的可打印ASCII字符(0x20至0x7E,包括0x20至0x7E),而不是A和空格(有关空格的规则然后转移到所选字符)。
  • 您的输出应仅包含两个表示操作的不同字符(您可以选择a和以外的其他字符r)。您可以选择打印单个尾随换行符。
  • 您的代码必须能够在一台合理的台式PC上在一分钟之内解决下面的任何测试用例(如果我花了两分钟的时间,我会带给您疑问的好处,但是如果花十分钟我会赢了) 't-我相信有可能在不到一秒钟的时间内解决所有问题的最佳算法。
  • 您不得针对个别测试用例优化代码(例如,通过对它们进行硬编码)。如果我怀疑有人这样做,我保留更改测试用例的权利。

您可以使用此CJam脚本进行相反的操作:这将花费一串构建说明并打印结果的杯子杯。(感谢Dennis重写了代码段,并显着加快了速度。)

Sp3000还出于相同的目的提供了此替代Python脚本

测试用例

在每个测试用例之后,都有一个数字,指示根据Ell的答案的最佳指令数。

                                       A
                                      A A
                                     A A A
                                    A A A A
                                   A A A A A
                                  A A A A A A
                                 A A A A A A A
                                A A A A A A A A
                               A A A A A A A A A
                              A A A A A A A A A A
                             A A A A A A A A A A A
                            A A A A A A A A A A A A
                           A A A A A A A A A A A A A
                          A A A A A A A A A A A A A A
                         A A A A A A A A A A A A A A A
                        A A A A A A A A A A A A A A A A
                       A A A A A A A A A A A A A A A A A
                      A A A A A A A A A A A A A A A A A A
                     A A A A A A A A A A A A A A A A A A A
                    A A A A A A A A A A A A A A A A A A A A
                   A A A A A A A A A A A A A A A A A A A A A
                  A A A A A A A A A A A A A A A A A A A A A A
                 A A A A A A A A A A A A A A A A A A A A A A A
                A A A A A A A A A A A A A A A A A A A A A A A A
               A A A A A A A A A A A A A A A A A A A A A A A A A
              A A A A A A A A A A A A A A A A A A A A A A A A A A
             A A A A A A A A A A A A A A A A A A A A A A A A A A A
            A A A A A A A A A A A A A A A A A A A A A A A A A A A A
           A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
          A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
         A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
        A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
       A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
      A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
     A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
    A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
   A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
  A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
 A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A

820
                                             A
                                            A A
                                           A A A
                                          A A A A
                                         A A A A A
                                        A A A A A A
                                       A A A A A A A
                                      A A A A A A A A
                     A               A A A A A A A A A
                    A A             A A A A A A A A A A
                   A A A           A A A A A A A A A A A
                  A A A A         A A A A A A A A A A A A
         A       A A A A A       A A A A A A A A A A A A A
        A A     A A A A A A     A A A A A A A A A A A A A A
   A   A A A   A A A A A A A   A A A A A A A A A A A A A A A
A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A

1946

               A
              A A
             A A A
            A A A A
           A A A A A
          A A A A A A
         A A A A A A A
        A A A A A A A A
       A A A A A A A A A               A
      A A A A A A A A A A             A A
     A A A A A A A A A A A           A A A
    A A A A A A A A A A A A         A A A A
   A A A A A A A A A A A A A       A A A A A       A
  A A A A A A A A A A A A A A     A A A A A A     A A
 A A A A A A A A A A A A A A A   A A A A A A A   A A A   A
A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A

2252

                                                         A A
                                                      A A A A
                                                   A A A A A A
                                                A A A A A A A A
                                             A A A A A A A A A A
                                          A A A A A A A A A A A A
                                       A A A A A A A A A A A A A A
                                    A A A A A A A A A A A A A A A A
                                 A A A A A A A A A A A A A A A A A A
                              A A A A A A A A A A A A A A A A A A A A
                           A A A A A A A A A A A A A A A A A A A A A A
                        A A A A A A A A A A A A A A A A A A A A A A A A
                     A A A A A A A A A A A A A A A A A A A A A A A A A A
                  A A A A A A A A A A A A A A A A A A A A A A A A A A A A
               A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
            A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
         A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
      A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
   A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A

9958

                   A A
                  A A A A
                 A A A A A A
                A A A A A A A A
               A A A A A A A A A A
              A A A A A A A A A A A A
             A A A A A A A A A A A A A A
            A A A A A A A A A A A A A A A A
           A A A A A A A A A A A A A A A A A A
          A A A A A A A A A A A A A A A A A A A A
         A A A A A A A A A A A A A A A A A A A A A A
        A A A A A A A A A A A A A A A A A A A A A A A A
       A A A A A A A A A A A A A A A A A A A A A A A A A A
      A A A A A A A A A A A A A A A A A A A A A A A A A A A A
     A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
    A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
   A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
  A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
 A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A

5540

A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A

10280

 A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A
A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A

10320

   A       A       A       A       A       A       A       A       A       A
  A A     A A     A A     A A     A A     A A     A A     A A     A A     A A
 A A A   A A A   A A A   A A A   A A A   A A A   A A A   A A A   A A A   A A A
A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A

5794

              A
             A A
            A A A
           A A A A                                               A
          A A A A A                                             A A
         A A A A A A A                                         A A A
        A A A A A A A A               A                       A A A A
       A A A A A A A A A             A A             A       A A A A A   A
      A A A A A A A A A A           A A A           A A     A A A A A A A A
     A A A A A A A A A A A         A A A A         A A A   A A A A A A A A A
    A A A A A A A A A A A A       A A A A A       A A A A A A A A A A A A A A
 A A A A A A A A A A A A A A     A A A A A A     A A A A A A A A A A A A A A A
A A A A A A A A A A A A A A A   A A A A A A A   A A A A A A A A A A A A A A A A

3297

                                                   A A
                                                  A A A
                                                 A A A A
                                                A A A A A
                                               A A A A A A
                                              A A A A A A A
                                             A A A A A A A A
                                            A A A A A A A A A
                                           A A A A A A A A A A     A
                                          A A A A A A A A A A A   A A
                                       A A A A A A A A A A A A A A A A
                                      A A A A A A A A A A A A A A A A A
                                     A A A A A A A A A A A A A A A A A A
      A                             A A A A A A A A A A A A A A A A A A A
     A A                           A A A A A A A A A A A A A A A A A A A A
    A A A             A A         A A A A A A A A A A A A A A A A A A A A A
   A A A A           A A A       A A A A A A A A A A A A A A A A A A A A A A
  A A A A A         A A A A     A A A A A A A A A A A A A A A A A A A A A A A
 A A A A A A     A A A A A A   A A A A A A A A A A A A A A A A A A A A A A A A
A A A A A A A   A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A

4081

                      A
                     A A       A                     A
                    A A A     A A                   A A A                 A
             A     A A A A   A A A A               A A A A     A         A A
  A         A A   A A A A A A A A A A         A   A A A A A   A A       A A A
 A A       A A A A A A A A A A A A A A       A A A A A A A A A A A     A A A A
A A A   A A A A A A A A A A A A A A A A     A A A A A A A A A A A A   A A A A A

4475

                                                             A              
      A           A                       A                 A A A   A       A
     A A         A A   A         A A     A A A   A         A A A A A A     A A
A   A A A A A   A A A A A   A   A A A   A A A A A A   A   A A A A A A A   A A A

5752

这意味着,最高可能的分数是64,515条指令。

Answers:


32

蟒蛇2,64,515

import sys

input = map(str.rstrip, sys.stdin.readlines())
width = (len(input[-1]) + 1) / 2
for i in range(len(input)):
    indent = len(input) - i - 1
    input[i] = [c != " " for c in input[i][indent::2]]
    input[i] += [False] * (width - indent - len(input[i]))
input = [[False] * n for n in range(width - len(input) + 1)] + input
working_area = [[False] * n for n in range(width + 1)]

def add():
    sys.stdout.write("a")
    for row in range(width + 1):
        for i in range(row):
            if not working_area[row][i] and (
                row == width or
                (working_area[row + 1][i] and working_area[row + 1][i + 1])
            ):
                working_area[row][i] = True
                return
def remove():
    sys.stdout.write("r")
    for row in range(width + 1):
        if True in working_area[row]:
            working_area[row][working_area[row].index(True)] = False
            return

for row in range(width, -1, -1):
    r = input[row]; R = working_area[row]
    for i in range(len(r) - 1, -1, -1):
        if r[i]:
            while not R[i]: add()
        else:
            while R[i]: remove()

结果

测试1 #1 - 820 #2 - 1946 #3 - 2252 #4 - 9958 #5 - 5540 #6 - 10280 #7 - 10320 #8 - 5794 #9 - 3297 #10 - 4081 #11 - 4475 #12 - 5752测试2 测试3
测试4 测试5 测试6
测试7 测试8 测试9
测试10 测试11 测试12

总计 64,515

说明

我们从一个空的“工作区”开始。我们以相反的读取顺序扫描输入,即从右到左和从下到上。如果输入与当前位置的工作区域之间不匹配(例如,输入中有杯子,但工作区域中没有杯子,反之亦然),我们可以在工作区域中添加或删除杯子按照规则进行操作,直到解决不匹配问题为止,然后我们继续移至下一个位置。

正确性

为了证明该方法是正确的,即结果序列生成了输入结构,足以表明我们从未修改(即,在已经访问过的位置上添加或移除杯子)(因为在我们访问过的每个位置上) ,我们确保工作区域与输入相匹配。)这很容易导致以下事实:我们以相反的顺序进行操作,即添加和移除杯子:

  • 位于位置l的杯子将始终在读取顺序为l的位置之后的杯子之前被移走,因此,在扫描顺序中位于l之前的杯子将不会被移走,因此不存在移走我们已经访问过的杯子的危险。
  • 类似地,在位置的杯将总是在扫描次序先于它,杯之前添加鉴于已经有它下面两杯(或它的在底部); 但是,由于我们已经拜访了这些地点,并因此添加了必要的杯子,并且如上所述,由于没有以后再将这些杯子取下的危险,因此满足了这一条件,因此没有在此处添加杯子的危险。我们已经访问过的位置。

最优性

请注意,从结构中添加或移除杯子的效果并不取决于用于生成结构的操作顺序,而仅取决于其当前配置。结果,给定生成特定结构的最佳操作序列S n = { s 1,...,s n },S n的每个初始段,即任何序列S m = { s 1,..。 。,小号 },其中ñ,也是最佳的序列,因为它会产生,否则会有比较短的序列相应的结构小号ñ,生成相同的结构。

我们可以证明,通过对最佳生成序列的长度进行归纳,我们的方法是最佳的:对于任何其最佳生成序列为空的结构(只有一个这样的结构-空结构),我们的方法显然会生成一个最佳序列。该方法为所有最佳序列长度为n的结构生成最佳序列,并考虑由最佳序列S n +1生成的结构。我们想证明,给定由S n +1生成的结构作为输入,我们的方法将产生相同的序列(或至少具有相同长度的序列)。

如上所述,S n也是一个最佳序列,因此,通过假设,我们的方法在给定由S n生成的结构作为输入的情况下产生了一个最佳序列。假设在不失一般性的情况下,S n是由我们的方法产生的序列(如果不是,我们总是可以用所述序列替换S n +1的前n个元素,并得到长度为n + 的序列令l为在S n +1(即s n +1)中最后一次操作修改的位置,并令S mS n的初始段,一旦它到达l(但在处理l之前),我们的程序就会产生该段。注意,由于由S nS n +1生成的结构在跟随l的所有位置上都一致,所以按读取顺序,S m在给定任一结构作为输入时都是相同的。

如果s n +1a(即杯子加法),则在读取顺序中l之前一定没有任何位置,可以在其中将杯子添加到S n生成的结构中。其结果是,子小号ñ以下小号必须是所有的a(因为一个r将意味着无论是有之前的空白,或小号ñ不是最优的。)当我们来到过程,我们需要在我们可以在l处添加杯子之前,精确地添加n-m个杯子,因此结果序列将为Sm,后跟 n-m +1个a元素,等于 S n +1(此后将不存在任何不匹配,因此这是生成的完整序列。)

同样,如果s n +1r,则在S n生成的结构中,按读取顺序,在l之前的位置一定不能有任何杯子。其结果是,的子序列小号Ñ以下小号必须全部。当我们处理l时,我们需要精确地删除n-m个杯子,然后才能在l处删除杯子,因此生成的序列为S m,后跟n-m + 1个元素,再次等于S n +1rr

换句话说,我们的方法为所述输入结构产生了最佳序列,因此,通过归纳为任何输入结构产生了最佳序列。

注意,这并不意味着该实现是最有效的。例如,绝对有可能直接在每个点上计算必须添加或删除的杯子的数量,而不是实际执行这些操作。

独特性

我们可以使用我们的方法的最优性来证明最优序列实际上是唯一的(也就是说,没有两个不同的最优序列会生成相同的结构。)我们再次对最优生成序列的大小进行归纳:空序列显然是空结构的唯一的最佳生成序列。假设长度为n的所有最佳生成序列都是唯一的,并考虑由两个最佳序列S n +1T n +1生成的结构Σ 。

回想一下,S nT n本身是最优的,因此,根据假设,它是唯一的。由于我们的方法产生了最佳序列,因此可以将S nT n视为由我们的方法生成的。令l Sl T分别为最后一次操作在S n +1T n +1中修改的位置,并假设l S在读取顺序上跟随或等于l T,而这并不失一般性。由于S n生成的结构T nl S之后的所有位置都一致,按阅读顺序,我们的方法产生的序列(以任一结构为输入)一旦达到l S(但在处理之前),则两者相同。把这个序列叫做ü

由于最后一个动作小号ñ +1修改小号,如果Σ有在杯子š则不得早任何空缺小号,如果Σ没有一个杯子在š则必须不存在任何l S之前的杯子,按阅读顺序排列。因此,跟随U的生成Σ的其余序列必须由重复应用同一条指令组成,这取决于杯子在l S处是否存在(否则不是最佳选择)。换句话说,S n +1T n +1是相等的(它们都以U开头,并以所述重复指令序列结尾),即Σ的最佳生成序列是唯一的,因此,通过归纳,所有最佳生成序列都是唯一的。

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.