9-棋盘覆盖问题


title: 9.棋盘覆盖问题
date: 2023-05-05 15:28:11
categories:

  • 大学课程内容
  • 大二下
  • 算法分析基础

9.棋盘覆盖问题

【问题描述】

给定一个2k×2k的棋盘(具体图例见教材),有一个特殊棋格,拥有一个特殊棋格的棋盘称为特殊棋盘。现要用四种L型骨牌(具体图例见教材)覆盖特殊棋盘上除特殊棋格外的全部棋格,不能重叠,找出覆盖方案。

【输入形式】

在屏幕上输入棋盘大小及特殊方格所在行号和列号

【输出形式】

输出使用L型骨牌进行棋盘覆盖结果

【样例输入】

2

1 2

【样例输出】

2 -1 3 3

2 2 1 3

4 1 1 5

4 4 5 5

【样例说明】

输入:第一行输入整数k表示棋盘大小为2的k次幂,若k为2,则棋盘大小为4行4列;第二行输入特殊方格所在的行号和列号,以空格分隔

输出:使用L型骨牌进行棋盘覆盖结果,由3个相同的数表示同一个L型骨牌,不同的骨牌用不同的数字表示。数字的大小表示棋盘覆盖的顺序。特殊方格在棋盘的第1行第2列,用-1表示。各整数间以空格分隔。

思路

使用数学归纳法可知这个问题一定有解,因此可以将整个棋盘分为四个部分,因为有障碍物的那个部分一定是有解的,我们可以把剩下的三个棋盘每个棋盘在切开的位置都看成有障碍物,因此剩下的三个棋盘就都有解了,在3个看成障碍物的地方可以使用一个L型进行覆盖

代码

k = int(input())
obstacle = tuple(map(int, input().split()))
board = [[0 for _ in range(2 ** k)] for _ in range(2 ** k)]
board[obstacle[0]-1][obstacle[1]-1] = -1
# 每个放置的L都需要自己的编号

cnt = 1

def chessboard(board, tr, tc, dr, dc, size):
    global cnt
    if size == 1:
        return
    s = size // 2
    t = cnt
    cnt += 1
    # 覆盖左上角子棋盘
    if dr < tr + s and dc < tc + s:
        chessboard(board, tr, tc, dr, dc, s)
    else:
        board[tr + s - 1][tc + s - 1] = t
        chessboard(board, tr, tc, tr + s - 1, tc + s - 1, s)
    # 覆盖右上角子棋盘
    if dr < tr + s and dc >= tc + s:
        chessboard(board, tr, tc + s, dr, dc, s)
    else:
        board[tr + s - 1][tc + s] = t
        chessboard(board, tr, tc + s, tr + s - 1, tc + s, s)
    # 覆盖左下角子棋盘
    if dr >= tr + s and dc < tc + s:
        chessboard(board, tr + s, tc, dr, dc, s)
    else:
        board[tr + s][tc + s - 1] = t
        chessboard(board, tr + s, tc, tr + s, tc + s - 1, s)
    # 覆盖右下角子棋盘
    if dr >= tr + s and dc >= tc + s:
        chessboard(board, tr + s, tc + s, dr, dc, s)
    else:
        board[tr + s][tc + s] = t
        chessboard(board, tr + s, tc + s, tr + s, tc + s, s)


chessboard(board, 0, 0, obstacle[0]-1, obstacle[1]-1, 2 ** k)
for i in range(2 ** k):
    for j in range(2 ** k):
        print(board[i][j], end=' ')
    print()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

重生之我是cxk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值