[R71B] 层层叠叠

  • 难度 入门
  • 时限 1s
  • 空限 256m
  • 模拟

思路

构造过程从外向内层层填充:第 ii 次(ii11 开始)用字符 sis_i 填满当时最外圈的边框。因此矩阵中某个格子属于第几层,取决于它到四边的最近距离,即第 dd 层(dd00 开始)的格子填的都是 sd+1s_{d+1}

m=2n1m = 2n - 1,格子 (r,c)(r, c) 到边框的距离为 d=min(r,c,m1r,m1c)d = \min(r, c, m-1-r, m-1-c)。逐格扫描整个矩阵:用数组 s 记录每层首次出现的字符,若同一层出现两个不同字符,则矩阵不是任何字符串的生成矩阵,输出 No;否则 s 即为所求字符串,输出 Yess

复杂度:时间 O(n2)O(n^2),空间 O(n)O(n)

仓颉实现

import std.convert.*
import std.env.*

main() {
    let reader = getStdIn()
    let n = Int64.parse(reader.readln().getOrThrow())
    let m = 2 * n - 1
    let s = Array<Rune>(n, { _ => r' ' })
    var ok = true
    for (r in 0..m) {
        let line = reader.readln().getOrThrow()
        let runes = line.toRuneArray()
        for (c in 0..m) {
            var d = r
            if (c < d) { d = c }
            if (m - 1 - r < d) { d = m - 1 - r }
            if (m - 1 - c < d) { d = m - 1 - c }
            let ch = runes[Int64(c)]
            if (s[Int64(d)] == r' ') {
                s[Int64(d)] = ch
            } else if (s[Int64(d)] != ch) {
                ok = false
            }
        }
    }
    if (!ok) {
        println("No")
    } else {
        println("Yes")
        for (ch in s) {
            print(ch)
        }
        println()
    }
}