棋盘覆盖

问题描述

在一个2k×2k 个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。

2.思路

1.当k>0时,将2k*2k棋盘分割为4个2(k-1)*2(k-1)子棋盘

2.将这三个无特殊方格的子棋盘转换为特殊棋盘,用一个L型骨盘覆盖这三个较小棋盘的会和处

3.递归地使用这种分割方法,直至棋盘简化为1*1棋盘,就结束递归。

3.注意

1.每次都对分割后的四个小棋盘进行判断,判断特殊方格是否在里面。

这里的判断的方法是每次先记录下整个大棋盘的左上角方格的行列坐标,然后再与特殊方格坐标进行比较,就可以知道特殊方格是否在该块棋盘中。

  1. 如果特殊方块在里面,这直接递归下去求即可,
  2. 如果不在,这根据分割的四个棋盘的不同位置,把右下角、左下角、右上角或者左上角的方格标记为特殊方块,然后继续递归。在递归函数里,还要有一个变量s来记录边的方格数,每次对棋盘进行划分时,边的方格数都会减半,这个变量是为了方便判断特殊方格的位置。

左上角方格的行列坐标是确定的,根据棋盘的大小和要判断在哪个区域确定

实现细节:

用4*4的棋盘举例

要判断特殊的方格在哪一个区域:

根据传入的参数size,leftRow,leftCol可以将棋盘划分为四个区域,然后和特殊点比较

1. 左上角:`specialRow < leftRow+size && specialCol < leftCol+size`
2. 右上角:`specialRow < leftRow+size && specialCol >= leftCol+size`
3. 左下角:`specialRow >= leftRow+size && specialCol < leftCol+size`
4. 右下角:`specialRow >= leftRow+size && specialCol >= leftCol+size`

填充的特殊点也可以用这几个参数来确定

​ 如果特殊点不在左上角,填充的特殊点在该区域的右下角leftRow+size-1,leftRol+size-1

​ 如果特殊点不在右上角,填充的特殊点在该区域的左下角leftRow+size-1,leftRol+size

​ 如果特殊点不在左下角,填充的特殊点在该区域的右上角leftRow+size,leftCol+size-1

​ 如果特殊点不在右下角,填充的特殊点在该区域的左下角leftRow+size,leftCol+size

2.递归的结束条件

  1. size为1时
//大小为1时,结束递归
if (1 == size) {
return;
}
  1. size为2时
//大小为2时,结束递归
if(size == 2){
number++;
if(specialCol != leftCol || specialRow != leftRow)
board[leftRow][leftCol] = number;
if(specialCol != leftCol+1 || specialRow != leftRow+1)
board[leftRow+1][leftCol+1] = number;
if(specialCol != leftCol+1 || specialRow != leftRow)
board[leftRow][leftCol+1] = number;
if(specialCol != leftCol || specialRow != leftRow+1)
board[leftRow+1][leftCol] = number;
return;
}

4.代码

package com.java.test;

public class ChessProblem {

    int size;//容量
int[][] board;//棋盘
int specialRow;//特殊点横坐标
static int number = 0;//L形编号,这个一定要是静态的,可以在任何地方访问到
int specialCol;//特殊点纵坐标 public ChessProblem(int specialRow, int specialCol, int size) {
this.size = size;
this.specialCol = specialCol;
this.specialRow = specialRow;
board = new int[size][size];
} //specialRow 特殊点的行下标
//specialCol 特殊点的列下标
//leftRow 矩阵的左边起点行下标
//leftCol 矩阵左边起点的列下标
//size 棋盘的宽或者高 public void setBoard(int specialRow, int specialCol, int leftRow, int leftCol, int size) {
//大小为1时,结束递归
if (1 == size) {
return;
} int subSize = size / 2;
number++;
int n = number;//注意这里一定要吧number存在当前的递归层次里,否则进入下一层递归全局变量会发生改变 //假设特殊点在左上角区域
if (specialRow < leftRow + subSize && specialCol < leftCol + subSize) {
setBoard(specialRow, specialCol, leftRow, leftCol, subSize);
}
else {
//不在左上角,设左上角矩阵的右下角就是特殊点(和别的一起放置L形)
board[leftRow + subSize - 1][leftCol + subSize - 1] = n;
setBoard(leftRow + subSize - 1, leftCol + subSize - 1, leftRow, leftCol, subSize);
} //假设特殊点在右上方
if (specialRow < leftRow + subSize && specialCol >= leftCol + subSize) {
setBoard(specialRow, specialCol, leftRow, leftCol + subSize, subSize);
}
else {
//不在右上方,设右上方矩阵的左下角就是特殊点(和别的一起放置L形)
board[leftRow + subSize -1][leftCol + subSize] = n;
setBoard(leftRow + subSize -1, leftCol + subSize, leftRow, leftCol + subSize, subSize);
} //特殊点在左下方
if (specialRow >= leftRow + subSize && specialCol < leftCol + subSize) {
setBoard(specialRow, specialCol, leftRow + subSize, leftCol, subSize);
}
else {
//不在左下方,设左下方矩阵的右上角就是特殊点(和别的一起放置L形)
board[leftRow + subSize][leftCol + subSize - 1] = n;
setBoard(leftRow + subSize, leftCol + subSize - 1, leftRow + subSize, leftCol, subSize);
} //特殊点在右下角
if (specialRow >= leftRow + subSize && specialCol >= leftCol + subSize) {
setBoard(specialRow, specialCol, leftRow + subSize, leftCol + subSize, subSize);
}
else {
//不在右下角,设右下角矩阵的左上就是特殊点(和别的一起放置L形)
board[leftRow + subSize][leftCol + subSize] = n;
setBoard(leftRow + subSize, leftCol + subSize, leftRow + subSize, leftCol + subSize, subSize);
}
} //输出棋盘
public void printBoard(int specialRow,int specialCol,int size) {
setBoard(specialRow, specialCol, 0, 0, size);
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board.length; j++) {
System.out.print(board[i][j] + "\t");
}
System.out.println();
}
} public static void main(String[] args) {
//棋盘的大小
int N = 8;
//特殊点的坐标
int specialRow = 0;
int specialCol = 1;
ChessProblem chessProblem = new ChessProblem(specialRow , specialCol , N);
chessProblem.printBoard(specialRow, specialCol, N);
} }

5.运行截图

棋盘覆盖(java实现)的更多相关文章

  1. 递归与分治策略之棋盘覆盖Java实现

    递归与分治策略之棋盘覆盖 一.问题描述 二.过程详解 1.棋盘如下图,其中有一特殊方格:16*16 . 2.第一个分割结果:8*8 3.第二次分割结果:4*4 4.第三次分割结果:2*2 5.第四次分 ...

  2. 棋盘覆盖(大数阶乘,大数相除 + java)

    棋盘覆盖 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 在一个2k×2k(1<=k<=100)的棋盘中恰有一方格被覆盖,如图1(k=2时),现用一缺角的 ...

  3. 棋盘覆盖问题(算法分析)(Java版)

    1.问题描述: 在一个2k×2k个方格组成的棋盘中,若有一个方格与其他方格不同,则称该方格为一特殊方格,且称该棋盘为一个特殊棋盘.显然特殊方格在棋盘上出现的位置有种情形.因而对任何 k≥0,有4k种不 ...

  4. NYOJ 45 棋盘覆盖

    棋盘覆盖 水题,题不难,找公式难 import java.math.BigInteger; import java.util.Scanner; public class Main { public s ...

  5. bzoj 2706: [SDOI2012]棋盘覆盖 Dancing Link

    2706: [SDOI2012]棋盘覆盖 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 255  Solved: 77[Submit][Status] ...

  6. NYOJ 45 棋盘覆盖 模拟+高精度

    题意就不说了,中文题... 小白上讲了棋盘覆盖,于是我就挖了这题来做. 棋盘覆盖的推导不是很难理解,就是分治的思想,具体可以去谷歌下. 公式就是f(k) = f(k - 1) * 4 + 1,再化解下 ...

  7. 棋盘覆盖(一) ACM

    棋盘覆盖 描述 在一个2k×2k(1<=k<=100)的棋盘中恰有一方格被覆盖,如图1(k=2时),现用一缺角的2×2方格(图2为其中缺右下角的一个),去覆盖2k×2k未被覆盖过的方格,求 ...

  8. CODEVS 2171 棋盘覆盖

    2171 棋盘覆盖 给出一张nn(n<=100)的国际象棋棋盘,其中被删除了一些点,问可以使用多少12的多米诺骨牌进行掩盖. 错误日志: 直接在模板上调整 \(maxn\) 时没有在相应邻接表数 ...

  9. JavaScript编写棋盘覆盖

    一.前言 之前做了一个算法作业,叫做棋盘覆盖,本来需要用c语言来编写的,但是因为我的c语言是半桶水(哈哈),所以索性就把网上的c语言写法改成JavaScript写法,并且把它的覆盖效果显示出来 二.关 ...

  10. TYVJ 1035 / codevs 2171 棋盘覆盖

    Problem Description 给定一个n * m的棋盘,已知某些各自禁止放置,求最多往棋盘上放多少长度为2宽度为1的骨牌(骨牌不重叠) Input 第一行为n,m(表示有m个删除的格子)第二 ...

随机推荐

  1. SpringBoot 整合 MongoDB 实战介绍

    一.介绍 在前面的文章中,我们详细的介绍了 MongoDB 的配置和使用,如果你对 MongoDB 还不是很了解,也没关系,在 MongoDB 中有三个比较重要的名词:数据库.集合.文档! 数据库(D ...

  2. ViewBinding 与 Kotlin 委托双剑合璧

    请点赞关注,你的支持对我意义重大. Hi,我是小彭.本文已收录到 GitHub · Android-NoteBook 中.这里有 Android 进阶成长知识体系,有志同道合的朋友,关注公众号 [彭旭 ...

  3. Redis变慢?深入浅出Redis性能诊断系列文章(二)

    (本文首发于"数据库架构师"公号,订阅"数据库架构师"公号,一起学习数据库技术) 本篇为Redis性能问题诊断系列的第二篇,本文主要从应用发起的典型命令使用上进 ...

  4. 在Windows 2012 R2上安装vcenter 5.5

    在Windows 2012 R2上安装vCenter 5.5做个实验,发现安装的时候卡在Install Directory service了. 重启后,再装也一样. 上网查了一下,说是要装好ADLDS ...

  5. 关于使用kubeoperator搭建k8s集群使用containerd作为容器运行时,从自己搭建的habor仓库拉取镜像的有关说明

    1.kubepi界面添加habor仓库信息,并授权给k8s集群 这一步的操作是当在工作负载选择从harbor仓库拉取镜像时会自动创建有关的secrets信息,从而不用事先手动创建了(有别于kuboar ...

  6. 解决zeal离线文档下载慢问题

    zeal简介 编程过程中难免会遇到不会用的关键字和方法,对我而言,在windows下,我使用Zeal这个软件进行离线文档查询. 问题 但是,在软件中下载DocSet(文档)会出现下载慢,或者下载不了的 ...

  7. MongoDB分片集群中配置参数说明

    replication:   #副本集的名称 replSetName: myshardrs01 sharding: #分片角色 clusterRole: shardsvr sharding.clust ...

  8. [笔记] 二维FFT

    假设现在有2个矩阵a和b,分别是n行m列和x行y列,现在你要计算它们的二维卷积,也就是求出矩阵s满足: \(s_{i,j}=\sum_{i'\leq i,j'\leq j}a_{i',j'}b_{i- ...

  9. WPF开发经验-实现Win10虚拟触摸键盘

    一 引入 项目有个需求,需要实现纯触控操作进行键盘输入.项目部署在Win10系统上,考虑有两种方案来实现. 通过调用Win10自带的触摸键盘来实现: 通过WPF实现一个触摸键盘来实现: 二 调用Win ...

  10. Hbase创建表参数说明

    Hbase创建表操作及参数说明 1.创建命名空间 create_namespace 'test' 2.创建user表,列族:info create 'test:user', 'info' 3.查看表结 ...