棋盘覆盖问题(Java)

2023-05-16

棋盘覆盖问题(Java)

文章目录

  • 棋盘覆盖问题(Java)
    • 1、问题描述
    • 2、算法设计思路
    • 3、代码实现
    • 4、复杂度分析
    • 5、参考


在这里插入图片描述


1、问题描述

在一个2k×2k个方格组成的棋盘中,若恰有一个方格与其他方格不同,则称该方格为一特殊方格,且称该棋盘为一个特殊棋盘。显然特殊方格在棋盘上出现的位置有4k 种情形.因而对任何k ≥ 0,有4k种不同的特殊棋盘。如下图中的特殊棋盘是当k = 2时16个特殊棋盘中的一个。
在这里插入图片描述

在棋盘覆盖问题中,要用下图所示的4种不同形态的L型骨牌覆盖一个给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。易知,在任何一个2k×2k的棋盘覆盖中,用到的L型骨牌个数恰好为(4k - 1)/3。

在这里插入图片描述

2、算法设计思路

使用分治策略,可以设计出解棋盘覆盖问题的简洁算法。

k>0时,将2k×2k棋盘分割为4个2k-1×2k-1 子棋盘,如下图(a)所示。

特殊方格必位于4个较小子棋盘之一中,其余3个子棋盘中无特殊方格。为了将这3个无特殊方格的子棋盘转化为特殊棋盘,可以用一个L型骨牌覆盖这3个较小棋盘的会合处,如下图(b)所示,从而将原问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种分割,直至棋盘简化为棋盘1×1
在这里插入图片描述

3、代码实现

特殊棋盘我们采用0来表示,同时假设特殊方格的位置为第三行第三列

棋盘一分为四之后,依次覆盖左上角子棋盘、右上角子棋盘、左下角子棋盘、右下角子棋盘。如若特殊方格在子棋盘中,则递归执行该子棋盘的操作;若不在,对于左上角子棋盘、右上角子棋盘、左下角子棋盘、右下角子棋盘而言,用编号为t的L型骨牌依次覆盖右下角、左下角、右上角、左上角的方格。

在这里插入图片描述

/**
 * TODO  棋盘覆盖算法 特殊棋盘我们采用0来表示
 *
 */
public class chessBoard {

    static final int SIZE = 4;
    static int[][] board = new int[SIZE][SIZE];
    static int title = 1; // title表示L型骨牌的编号

    public static void main(String[] args) {
        // TODO 假设特殊方格的位置为第三行第三列
        board[2][2] = 0;
        ChessBoard(0, 0, 2, 2, SIZE);

        System.out.println(SIZE + "*" + SIZE + "的L型骨牌棋盘为:");
        for (int i = 0; i < SIZE; ++i) {
            for (int j = 0; j < SIZE; j++) {
                System.out.print(board[i][j] + "  ");
            }
            System.out.println();
        }
    }


    /**
     *
     * @param tr    表示棋盘左上角行号
     * @param tc    表示棋盘左上角列号
     * @param dr    表示特殊棋盘的行号
     * @param dc    表示特殊棋盘的列号
     * @param size  =2^k。棋盘的规格为2^k*2^k
     */
    public static void ChessBoard(int tr, int tc, int dr, int dc, int size) {
        if (size == 1) {
            return;
        }
        int t = title++;    // t表示L型骨牌的编号
        int s = size / 2;   // 分割的子棋盘的规格大小(切分为4个子棋盘)

        // TODO 1.覆盖左上角子棋盘
        if (dr < tr + s && dc < tc + s) {
            // TODO 说明特殊方格在此子棋盘中
            ChessBoard(tr, tc, dr, dc, s);
        } else {
            // TODO 说明特殊方格不在此子棋盘中
            //  用t号L型棋盘覆盖这个子棋盘的右下角
            board[tr + s - 1][tc + s - 1] = t;
            // TODO 覆盖其余棋盘方格
            ChessBoard(tr, tc, tr + s - 1, tc + s - 1, s);
        }

        // TODO 2.覆盖右上角子棋盘
        if (dr < tr + s && dc >= tc + s) {
            ChessBoard(tr, tc + s, dr, dc, s);
        } else {
            // 用t号L型棋盘覆盖这个子棋盘的左下角
            board[tr + s - 1][tc + s] = t;
            ChessBoard(tr, tc + s, tr + s - 1, tc + s, s);
        }

        // TODO 3.覆盖左下角子棋盘
        if (dr >= tr + s && dc < tc + s) {
            ChessBoard(tr + s, tc, dr, dc, s);
        } else {
            // 用t号L型棋盘覆盖这个子棋盘的右上角
            board[tr + s][tc + s - 1] = t;
            ChessBoard(tr + s, tc, tr + s, tc + s - 1, s);
        }

        // TODO 4.覆盖右下角子棋盘
        if (dr >= tr + s && dc >= tc + s) {
            ChessBoard(tr + s, tc + s, dr, dc, s);
        } else {
            // // 用t号L型棋盘覆盖这个子棋盘的左上角
            board[tr + s][tc + s] = t;
            ChessBoard(tr + s, tc + s, tr + s, tc + s, s);
        }

    }
}

4、复杂度分析

设T(k)是算法chessBoard覆盖一个2k×2k棋盘所需的时间。从算法的分隔策略可以知道,T(k)满足以下的递归方程:

  • 当k = 0时,T(k) = O(1),

  • 当k > 0时,T(k) = 4T(k - 1) + O(1)

最终此递归方程可得:T(n) = O(4k)。
由于覆盖2k×2k棋盘所需的L型骨牌个数为(4k - 1)/3,所以此算法是一个在渐进意义下的最优算法。
在这里插入图片描述

5、参考

  • 算法分析与设计(第四版)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

棋盘覆盖问题(Java) 的相关文章

  • Java中RandomAccessFile的并发

    我正在创建一个RandomAccessFile对象通过多个线程写入文件 在 SSD 上 每个线程都尝试在文件中的特定位置写入直接字节缓冲区 并且我确保线程写入的位置不会与另一个线程重叠 file getChannel write buffe
  • jvm中本机代码如何转换为机器代码[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我读过一些文章说 jvm将字节码转换为机器码 jvm将字节码转换为本机代码 jvm 将字节码转换为系统调用 系统调用又由操作系统与硬件
  • 通过 html tidy 提供渲染 jsp 页面

    我有一个在 Glassfish 上运行的 Java 项目 它会呈现一些难看的 HTML 这是使用各种内部和外部 JSP 库的副作用 我想设置某种渲染后过滤器 通过 HTMLTidy 提供最终的 HTML 这样源代码就很好且整洁 有助于调试
  • Glassfish:在部署期间修改 EAR 的部署描述符

    经过几天的搜索 尝试和摇头 我将这个问题发布到 SO 尽管它seems已经得到答复 这是场景 我有一个 EAR 应用程序 目前 包含一个 WAR 和一个 EJB 模块 EJB 模块使用 JPA persistence xml 并且一些无状态
  • 如何为java注释处理器编写自动化单元测试?

    我正在尝试使用 java 注释处理器 我可以使用 JavaCompiler 编写集成测试 事实上我现在正在使用 hickory 我可以运行编译过程并分析输出 问题 即使我的注释处理器中没有任何代码 单个测试也会运行大约半秒 对于以 TDD
  • MediaPlayer.create() 始终返回 null

    我以前用过媒体播放器 从来没有遇到过这个问题 每当我尝试使用 MediaPlayer create 时 该方法都会给我 null 并且我无法播放声音 我有什么遗漏的吗 public class Game extends Activity p
  • c和java语言中的换行符

    现在行分隔符取决于系统 但在 C 程序中我使用 n 作为行分隔符 无论我在 Windows 还是 Linux 中运行它都可以正常工作 为什么 在java中 我们必须使用 n 因为它与系统相关 那么为什么我们在c中使用 n 作为新行 而不管我
  • EMF Eclipse:带有自定义字段(属性)的枚举

    好吧 在 Java 中这是可能的 import org eclipse emf common util Enumerator public enum MyEnum implements Enumerator LITERAL1 0 Name
  • 按文件名过滤 eclipse 中的警告

    我们使用 Eclipse 进行 Java 开发 并使用 Maven 将 JSP 编译成 servlet 以便在嵌入式 Jetty 实例中使用 这意味着要从 Eclipse 运行该项目 我必须包含 target jsp source 作为源文
  • spring mvc 跟踪引用页面

    在基于注释的弹簧控制器中 如果用户正在url com first page并点击一个链接或提交一份表格指出url com second page 如何制作second page知道url of first page所以这样second pa
  • org.apache.commons.codec.digest.Md5Crypt.md5Crypt 函数。 linux下出现异常,windows下正常

    我们正在使用commons codec加密密码 使用org apache commons codec digest Md5Crypt md5Crypt功能 在Windows环境下工作正常 但在CentOS上却抛出异常 我们有3台centOS
  • java中日期转换dd-MMM-yyyy到dd-MM-yyyy

    在Java中将23 Mar 2011转换为23 03 2011的最简单方法是什么 感谢大家 这似乎解决了这个问题 try Calendar cal Calendar getInstance cal setTime new SimpleDat
  • 使用 Box2d(适用于 Android)进行碰撞检测?

    有人可以解释一下使用 box2d for android 进行碰撞检测的工作原理吗 我无法理解 BBContactListener 以什么方式工作 BBContactListener listener new BBContactListen
  • ASTParser:解析绑定后查找声明节点

    我创建了一个启用了绑定的 AST 当我稍后解析绑定时 我得到了一个有效的 ITypeBinding 但是 当我想要获取绑定的声明 Node 时 它 总是返回 null 除非 ITypeBinding 在 sourceFile 中声明 这是我
  • Struts2中的变量声明

    Struts2中如何声明变量并为该变量赋值 使用设置标签
  • AndroidAnnotations 和 Dagger

    我正在尝试使用 Dagger 注入 Android 带注释的 Activity java lang IllegalArgumentException No inject registered for members com app serv
  • 如何创建具有同等时间元素的 JavaFX 转换?

    我正在尝试 JavaFX 和动画 尤其是PathTransition 我正在创建一个简单的程序 使球 弹跳 而不使用QuadCurveTo班级 到目前为止 这是我的代码 Ellipse ball new Ellipse 375 250 10
  • Retrofit 2.0:预期为 BEGIN_OBJECT,但在第 1 行第 1 列路径 $ [重复] 处为 STRING

    这个问题在这里已经有答案了 我在邮递员上传递了更新用户请求并获得了成功的响应 参见图片 现在当我尝试使用 Retrofit 2 在我的应用程序中执行相同操作时 出现错误 com google gson JsonSyntaxException
  • 使用 PDFBox 在 Android 中创建 PDF

    我正在尝试通过我的 Android 应用程序创建 PDFPDFBoxapi 但出现以下错误 java lang NoClassDefFoundError org apache pdfbox pdmodel PDDocument 我已经将以下
  • Java 可变 BigInteger 类

    我正在使用 BigIntegers 进行计算 该计算使用一个调用 multiply 大约 1000 亿次的循环 并且从 BigInteger 创建新对象使其非常慢 我希望有人编写或找到了 MutableBigInteger 类 我在 jav

随机推荐

  • 执行MapReduce报错:无法分配内存 (errno=12)

    执行MapReduce报错 xff1a 无法分配内存 errno 61 12 文章目录 执行MapReduce报错 xff1a 无法分配内存 errno 61 12 0 写在前面1 程序介绍2 报错解决3 参考 0 写在前面 Linux U
  • 离线数仓之Kerberos基本使用及问题记录

    离线数仓之Kerberos基本使用及问题记录 文章目录 离线数仓之Kerberos基本使用及问题记录0 写在前面1 Kerberos基本使用0 启动Kerberos相关服务1 安全模式下启动Hadoop集群 2 安装Kerberos客户端访
  • jps查看进程出现「xxxx -- process information unavailable」

    jps查看进程出现 xxxx process information unavailable 文章目录 jps查看进程出现 xxxx process information unavailable 0 写在前面1 报错2 参考 0 写在前面
  • CentOS7.X时间调整为系统时间之后,重新开机就无效了

    CentOS7 X时间调整为系统时间之后 xff0c 重新开机就无效了 文章目录 CentOS7 X时间调整为系统时间之后 xff0c 重新开机就无效了0 原因分析1 时间修改2 参考 0 原因分析 系统时区非上海 没有同步网络时间 1 时
  • MongoDB的「Linux」安装及基本使用

    MongoDB的 Linux 安装及基本使用 文章目录 MongoDB的 Linux 安装及基本使用0 写在前面1 下载并安装MongoDB2 启动方式2 1 直接启动2 2 以 配置文件 方式启动2 2 1 使用默认配置文件2 2 2 自
  • MapReduce报错:「MKDirs failed to create file」

    MapReduce报错 xff1a MKDirs failed to create file 文章目录 MapReduce报错 xff1a MKDirs failed to create file 0 写在前面1 程序代码及报错信息输入 输
  • Hive执行脚本: Return Code 2 from org.apache.hadoop.hive.ql.exec.MapRedTask

    Hive执行脚本 Return Code 2 from org apache hadoop hive ql exec MapRedTask 文章目录 Hive执行脚本 Return Code 2 from org apache hadoop
  • Hive on Tez 的安装配置

    Hive on Tez 的安装配置 文章目录 Hive on Tez 的安装配置0 写在前面1 起源2 Tez概述3 安装部署4 解决日志Jar包冲突 0 写在前面 Hadoop xff1a Hadoop 2 9 2Hive xff1a H
  • 执行Hive查询时出现OOM

    执行Hive查询时出现OOM 文章目录 执行Hive查询时出现OOM写在前面报错 xff1a Error Java heap space实验场景日志信息StckOverFlow的回答 写在前面 Hive执行引擎 xff1a Hive on
  • android 信息(mms)的故事(五)-- 发彩信

    发彩信和发短信一样 xff0c 在ComposeMessageActivity java界面都是从onclick xff08 xff09 sendMessage xff08 xff09 开始 xff0c 同样的发送前检查收件人是否有效 xf
  • flume----HDFS sink 启动时产生大量小文件处理办法

    flume HDFS sink 启动时产生大量小文件处理办法 转载自 xff1a https blog csdn net qq 37714755 article details 113243139 1 问题背景 通过flume直接上传实时数
  • Python3操作MongoDB数据库

    Python3操作MongoDB数据库 文章目录 Python3操作MongoDB数据库0 写在前面1 安装开源驱动库pymongo2 参考 0 写在前面 Linux xff1a Ubuntu Kylin 16 04MongoDB xff1
  • Linux好用的管道命令

    Linux好用的管道命令 文章目录 Linux好用的管道命令1 选取命令grepcut 分割 2 排序命令sortwcuniq 3 划分命令 split4 参数代换xargs5 数据处理工具awk 6 sed工具7 参考 1 选取命令 gr
  • 关于Hadoop集群物理及虚拟内存的检测的设置说明

    关于Hadoop集群物理及虚拟内存的检测的设置说明 文章目录 关于Hadoop集群物理及虚拟内存的检测的设置说明写在前面正文不能关闭对物理内存的检测关闭对虚拟内存的检测 参考 写在前面 Linux xff1a CentOS7 5Java x
  • Arrays.stream().boxed()的使用

    Arrays stream boxed 的使用 文章目录 Arrays stream boxed 的使用0 写在前面1 Arrays stream 的使用算法 xff1a 代码 xff1a 输出结果 xff1a 2 boxed 的使用box
  • Flume中 File Channel 的优化

    Flume中 File Channel 的优化 文章目录 Flume中 File Channel 的优化File Channel 的特点File Channel 的优化索引索引备份 Flume官方优化设计概述 xff08 Overview
  • 数仓采集通道的设计

    数仓采集通道的设计 文章目录 数仓采集通道的设计写在前面方案一 xff1a 方案二 xff1a 方案三 xff1a 最终方案 写在前面 离线和实时数仓共用一套数据采集通道系统数据采集存储到HDFS上完全分布式 xff08 三台节点 xff0
  • Hive命令使用记录

    Hive命令使用记录 文章目录 Hive命令使用记录操作一些常用的Bash Shell 命令 xff1a 操作HDFS 平台相关的命令 xff1a 查看当前使用的数据库创建表的时候通过location 指定数据存储位置 xff0c 加载数据
  • Navicat远程连接Linux的MySQL服务Error10061的解决方案

    Navicat远程连接Linux的MySQL服务Error10061的解决方案 文章目录 Navicat远程连接Linux的MySQL服务Error10061的解决方案写在前面解决方法 写在前面 Linux xff1a Ubuntu Kyl
  • 棋盘覆盖问题(Java)

    棋盘覆盖问题 xff08 Java xff09 文章目录 棋盘覆盖问题 xff08 Java xff09 1 问题描述2 算法设计思路3 代码实现4 复杂度分析5 参考 1 问题描述 在一个2k 2k个方格组成的棋盘中 若恰有一个方格与其他