最简单的地板砖


10

您应该编写一个程序或函数,该程序或函数接收一个描述地板的字符串作为输入并输出或返回最简单的元平铺区域,该区域可以创建给定的地板图案。

地板是正方形网格的一部分。每个方形图块都用天蓝色或黑色上色(由ab在输入中表示)。

一个示例楼层:

  aaaa
ababab
aaaaa

元平铺

  • 由一个NM天蓝色和黑色正方形组成的矩形meta-tile 构建
  • 直到平移为止,使用的元瓦片都是相同的(您不能旋转或镜像它们)
  • 如果两个meta-tile的边连接,则它们应沿其整个长度连接(即meta-tiles以网格状方式平铺空间)

元区块示例:

ba
aa

以及它创建的元平铺:

       .
       .
       .
    babababa
    aaaaaaaa
... babababa ...
    aaaaaaaa    
    babababa
    aaaaaaaa
       .
       .
       .

此元平铺会创建显示的上方楼层,如左侧字母所示:

       .
       .
       .
    ********
    ***aaaa*
... *ababab* ...
    *aaaaa**    
    ********
    ********
       .
       .
       .

如果meta-tile的区域较小,则meta-tiling比另一个更简单。2*2 = 4对于示例楼层,我们的示例的面积最小。因此输出应4为示例。

输入值

  • 由字符组成a b spacenewline至少包含一个a或的字符串b
  • 字母(ab)形成一种4联(并排连接)的形状。
  • 行的开头将没有多余的空间,即,至少会有一行以a或开头b
  • 您可以选择两种输入格式:

    • 行末没有多余的空格(如示例所示)。
    • 行右侧的空格使所有行的长度与最长的行相同。
  • 尾随换行符是可选的。

输出量

  • 一个整数,即最小可能的元区块的面积,其图块中包含输入楼层。

例子

示例以短划线分隔。示例的三个部分是输入,输出和可能的最小元拼贴之一。

a

1

a
-----------------
 aaaa
aaa
a

1

a
-----------------
aabaab
abaa
aaba

6

aab
aba
-----------------
aabaab
a  a a
aabab

18

aabaab
aaaaaa
aababa
-----------------
ba
aaab

8

baaa
aaab
-----------------
 aaaa
ababb
aaaa

10

aaaaa
ababb
-----------------
 a aa
ab ba
 aba

6

aa
ab
ba
-----------------
 aaaa
abab
aaaa

4

aa
ab
-----------------
ba
 ba
  b

4

ba
ab
-----------------
baa
aba
aab

9

baa
aba
aab
-----------------
 aaaa
aabaa
aaaa

6

aaa
aab

这是代码高尔夫球,因此最短的入场券获胜。


@Ypnypn每个角都必须触摸其他3个角(平铺边缘上的meta-tiles除外)。我将其描述为“如果两个meta-tile的边连接在一起,则它们应沿其整个长度连接”。因此,您给出的示例是非法的。
randomra

Answers:


3

C-208字节

w,q,n,m,r,g,u;t(char*f){for(w=0;f[w++]-10;);for(q=1;;q++)for(n=1;m=q/n,n<=q;++n)if(n*m==q){char t[q];bzero(t,q);r=q;for(g=0;f[g];++g){u=g/w%m*n+g%w%n;r=t[u]+f[g]-195?r:0;if(f[g]&64)t[u]=f[g];}if(r)return r;}}

打高尔夫球之前的等效代码:

#include <stdio.h>
#include <strings.h>

int t(char* f) {
    int w = 0;
    for ( ; f[w++] - 10; );

    for (int q = 1; ; q++) {
        char t[q];
        for (int n = 1; n <= q; ++n) {
            int m = q / n;
            if (n * m == q) {
                bzero(t, q);
                int r = q;
                for (int g = 0; f[g]; ++g) {
                    int u = g / w % m * n + g % w % n;
                    if (t[u] + f[g] == 195) {
                        r = 0;
                    }
                    if (f[g] & 64) {
                        t[u] = f[g];
                    }
                }
                if (r) {
                    return r;
                }
            }
        }
    }
}

该算法是蛮力的,因此它应该在代码的基础上是相当明显的。无论如何,这里有一些评论:

  • 输入应该具有尾随空格的形式,以便所有行都具有相同的长度。
  • First循环通过查找第一个换行符来找到宽度。
  • 外循环超过候选元块大小qreturn当meta-tile可以覆盖地板时,以a 退出。请注意,循环不需要其他退出条件,因为总有解决方案(最坏的情况是输入大小)。
  • 第一个嵌套循环及其后if枚举了size的有效元拼贴宽度/高度组合q
  • 与候选元区块大小匹配的字符数组将初始化为零。
  • 内循环遍历地板上的所有瓷砖。
  • u 是对应于地砖的meta-tile中的索引。
  • 如果两个地砖和元瓷砖瓷砖是ab与不同(的总和a = 97,并b = 98195),存在不匹配,并与试图尺寸行不通元平铺尺寸。
  • 否则,如果地砖为ab,则将地砖颜色复制到候选meta-tile。
  • 成功进行匹配时(即,未将尝试匹配标记为失败),返回meta-tile的大小。

使用的测试代码:

#include <stdio.h>

extern int t(char* s);

int main()
{
    printf("%d\n", t(
        "a\n"
    ));
    printf("%d\n", t(
        " aaaa\n"
        "aaa  \n"
        "a    \n"
    ));
    printf("%d\n", t(
        "aabaab\n"
        "abaa  \n"
        "aaba  \n"
    ));
    printf("%d\n", t(
        "aabaab\n"
        "a  a a\n"
        "aabab \n"
    ));
    printf("%d\n", t(
        "ba  \n"
        "aaab\n"
    ));
    printf("%d\n", t(
        " aaaa\n"
        "ababb\n"
        "aaaa \n"
    ));
    printf("%d\n", t(
        " a aa\n"
        "ab ba\n"
        " aba \n"
    ));
    printf("%d\n", t(
        " aaaa\n"
        "abab \n"
        "aaaa \n"
    ));
    printf("%d\n", t(
        "ba \n"
        " ba\n"
        "  b\n"
    ));
    printf("%d\n", t(
        "baa\n"
        "aba\n"
        "aab\n"
    ));
    printf("%d\n", t(
        " aaaa\n"
        "aabaa\n"
        "aaaa \n"
    ));
    return 0;
}

输出:

1
1
6
18
8
10
6
4
4
9
6
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.