网格中最大的正方形[关闭]


10

挑战

给定这样的网格

  1 2 3 4 5 6 7 8
1 . . . . . . . .
2 . # . . . # . .
3 . . . . . . . .
4 . . . . . . . .
5 . . . . . . . .
6 . . # . . . . .
7 . . . . . . . .
8 . . . . . . . .

编写一段代码来确定不包含“#”的最大正方形的大小。(此输入的答案是5x5,因为右下5x5网格是最大的正方形)。

正方形必须具有平行于x和y轴的边。

作为一些小细节:原始网格始终是正方形,并且其边长已指定。还提供了“#”符号的坐标。

输入详细信息

第一行:N(1 <= N <= 1000),方格的边长,T(1 <= T <= 10,000)个“#”号。

接下来的T行:每个T#的坐标

测试用例

输入#1:

8 3
2 2
2 6
6 3

结果1:5

================

输入#2:

8 4
1 1
1 8
8 1
8 8

结果2:6

================

输入#3:

5 1
3 3

结果3:2

这是一个问题,因此在rextester编译器上测试的最快的代码胜出。

玩得开心!



3
不过对于fastest-code1000x1000来说太小了
l4m2 '18年

1
但是rextester不支持Jelly或Hexagony。
user202729 '18

6
像rextester一样强大,我是否建议您使用在线尝试呢?它包含更多语言,并且是社区运行的。
ATaco

1
“在rextester编译器上测试的最快代码胜出”-在什么输入上最快?
纳撒尼尔(Nathaniel)'18

Answers:


1

Node.js

将输入作为(w,l),其中w是宽度,l是坐标[x,y]的数组。(如果输入格式确实像所述的一样严格,则可以更改。)在O(w²)中工作

f = (w, l) => {
  var x, y,
      W = w * w,
      a = new Uint16Array(W),
      best = 0;

  l.forEach(([x, y]) => a[(y - 1) * w + x - 1] = 1);

  for(y = w; y < W; y += w) {
    for(x = y + 1; x < y + w; x++) {
      if(a[x]) {
        a[x] = 0;
      }
      else {
        best = Math.max(
          best,
          a[x] = Math.min(a[x - 1], a[x - w], a[x - w - 1]) + 1
        );
      }
    }
  }

  return best;
}

在线尝试!


console.log(f( 1000, [...Array(10000)].map(_=>[Math.random()*1000+1|0,Math.random()*1000+1|0]) )); 花费了114毫秒,尽管这可能是该语言的低效率
l4m2 '18年

JIT编译后,它更像是f()内部的8ms。(但是是的...答案不会那样评分。)
Arnauld

我怀疑OP是否会添加更客观的获胜标准...
user202729 '18

1

C(gcc)

这里没有花哨的算法,几乎是蛮力的……但是,C很快。

输入:stdin输入

输出:将输出写入stdout

#include <stdio.h>
#include <stdint.h>

int main(void) {
    uint_fast16_t n, t, i, j, h, x, y, flag, biggest = 0;
    scanf("%hi %hi", &n, &t);
    uint_fast8_t m[n][n];
    for (uint_fast16_t c = 0; c < t; ++c) {
        scanf("%hi %hi", &i, &j);
        m[i-1][j-1] = '#';
    }
    for (i = 0; i < n - 1; ++i) {
        for (j = 0; j < n - 1; ++j) {
            flag = 1;
            for (h = 1; flag && i + h < n + 1 && j + h < n + 1; ++h) {
                for (y = i; flag && y < i + h; ++y) {
                    for (x = j; flag && x < j + h; ++x) {
                        if (m[y][x] == '#') flag = 0;
                    }
                }
                if (flag && h > biggest) biggest = h;
            }
        }
    }
    printf("%d", biggest);
}

在线尝试!

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.