有缺陷的棋盘问题——寻找伪代码算法(分治法)
Posted
技术标签:
【中文标题】有缺陷的棋盘问题——寻找伪代码算法(分治法)【英文标题】:Defective chessboard problem - looking for pseudocode algorithm (divide&conquer) 【发布时间】:2020-09-05 19:49:14 【问题描述】:我应该使用分而治之的范式来设计一个递归算法“CBCover”,它确定了运行时 O(n^2) (n = 2^k) 中的覆盖率(如下图所示)。
CBCover的入口/输入应该是(k, a, b),其中k定义了棋盘的大小,(a, b)是缺失字段的坐标。
可能的覆盖范围:
4x4 棋盘丢失 (4, 1):
有人知道伪代码是什么样子的吗?
【问题讨论】:
欢迎来到 SO!所以你只能使用单个“L”三联牌来平铺? This question 似乎有更完整的问题陈述。你有没有尝试解决这个问题,你能分享你的想法吗?谢谢。 【参考方案1】:算法可以如下:
确定四个象限中的哪个象限缺少字段。将 L 形块放置在网格的中心,使其占据其他三个象限中的每个象限中的一个字段。现在您有四个象限,每个象限都有一个不能再使用的字段。应用相同的策略递归地求解每个象限。当当前网格没有可用字段时递归停止,即它是一个由不可用字段组成的 1x1 网格。
您可以使用不同的数据结构来描述镶嵌。一种方法是创建一个 2D 网格,其中每个单元格都获得一个唯一标识其所属形状的值。所以具有相同值的单元格属于一起。
上述算法可以从一个网格开始,它首先为每个单元格(0、1、2、...等)分配一个唯一的值,然后当它们必须属于同一单元格时,将值从一个单元格复制到另一个单元格形状。
这是一个简单的 javascript 实现。它是交互式的,因此您可以通过单击按钮更改输入,并将鼠标悬停在网格上,您可以识别“缺失字段”:
// Main algorithm:
function tile(k, a, b)
let length = 2**k;
// Create a grid where each cell has a unique value
let grid = [];
for (let y = 0; y < length; y++)
let row = [];
for (let x = 0; x < length; x++)
row.push(y*length + x); // unique value
grid.push(row);
a = a % length;
b = b % length;
function recur(length, a, b, top, left)
if (length == 1) return;
let half = length / 2;
let midrow = top + half;
let midcol = left + half;
let quadrant = (a >= midrow) * 2 + (b >= midcol);
let val = -1;
for (let i = 0; i < 4; i++)
let quadTop = i >= 2 ? midrow : top;
let quadLeft = i % 2 ? midcol : left;
let row, col;
if (quadrant == i)
row = a;
col = b;
else
row = midrow - 1 + (i >> 1);
col = midcol - 1 + (i % 2);
// Add this cell to an L-shape
if (val == -1) val = grid[row][col];
else grid[row][col] = val; // join with neighboring cell
recur(half, row, col, quadTop, quadLeft);
recur(length, a, b, 0, 0);
return grid;
// Parameters of the problem
let k, a, b;
// I/O handling:
function solve(newK, newA, newB)
if (newK <= 0) return; // grid must be at least 2x2
k = newK;
a = newA;
b = newB;
let grid = tile(k, a, b);
display(grid);
let table = document.querySelector("table");
function display(grid)
table.innerhtml = "";
for (let y = 0; y < grid.length; y++)
let tr = table.insertRow();
for (let x = 0; x < grid.length; x++)
let val = grid[y][x];
cls = "";
if (y && val === grid[y-1][x]) cls += " up";
if (grid[y+1] && val === grid[y+1][x]) cls += " down";
if (val === grid[y][x-1]) cls += " left";
if (val === grid[y][x+1]) cls += " right";
if (cls === "") cls = "gap";
tr.insertCell().className = cls.trim();
// Allow user to select gap with a click on a cell:
table.addEventListener("mousemove", (e) =>
let td = e.target;
if (td.tagName !== "TD") return;
solve(k, td.parentNode.rowIndex, td.cellIndex);
);
// Allow user to change the size of the grid:
document.querySelector("#dbl").addEventListener("click", () => solve(k+1, a, b));
document.querySelector("#hlf").addEventListener("click", () => solve(k-1, a, b));
// Create, solve and display initial grid
solve(2, 0, 0);
table border-collapse: collapse
td border: 1px solid; width: 10px; height: 10px
.gap background: silver
.up border-top-color: transparent
.down border-bottom-color: transparent
.left border-left-color: transparent
.right border-right-color: transparent
<button id="dbl">Increase size</button><button id="hlf">Decrease size</button><br><br>
<table></table><br>
【讨论】:
以上是关于有缺陷的棋盘问题——寻找伪代码算法(分治法)的主要内容,如果未能解决你的问题,请参考以下文章