棋盘覆盖(Java)
棋盘覆盖(Java)
一、问题描述
在一个 2^k * 2^k 方格组成的棋盘中,若恰有一个方格与其它方格不同,则称该方格为一个特殊方格,且称该棋盘为一个特殊棋盘。用4种不同形态的L型骨牌覆盖一个给定的特殊棋盘(即特殊方格的位置已经确定了)上除特殊方格外的所有方格,且任何两个L型骨牌不得重复覆盖。
二、实现思路:
棋盘覆盖实现的基本方法为分治法,分治法的基本思路:将一个规模为n的问题分解为k个规模较小的子问题,这些子问题相互独立且与原问题相同。递归地解决这些子问题,然后将各个子问题的解合并得到原问题的解。简单地说,就是将规模为n的问题自顶向下分解,直到子问题分解到足够小,可以容易解决时,再自底向上合并,从而得到原来的解。
分析思路:当k>0时,将2k*2k棋盘分割为4个2(k-1)*2(k-1)子棋盘,特殊方格必定位于这四个小棋盘中,其余三个子棋盘没有特殊方格,为了将这三个无特殊方格的子棋盘转换为特殊棋盘,我们可以用一个L型骨盘覆盖这三个较小棋盘的会合处,如图所示:
从图上可以看出,这三个子棋盘上被L型骨牌覆盖的方格就成为该棋盘上的特殊方格,从而将问题分解为4个较小规模的棋盘覆盖问题。递归地使用这种分割方法,直至棋盘简化为1*1棋盘,就结束递归。
三、算法算法流程分析:
实现这种算法的分析:每次都对分割后的四个小方块进行判断,判断特殊方格是否在里面。这里的判断的方法是每次先记录下整个大方块的左上角方格的行列坐标,然后再与特殊方格坐标进行比较,就可以知道特殊方格是否在该块中。如果特殊方块在里面,这直接递归下去求即可,如果不在,这根据分割的四个方块的不同位置,把右下角、左下角、右上角或者左上角的方格标记为特殊方块,然后继续递归。在递归函数里,还要有一个变量s来记录边的方格数,每次对方块进行划分时,边的方格数都会减半,这个变量是为了方便判断特殊方格的位置。
四、实现代码:
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];}//leftRow矩阵的左边起点行下标 leftCol矩阵左边起点的列下标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 printBoard1(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 void printBoard(int specialRow,int specialCol,int size) {board[specialRow][specialCol]=-1;for (int i = 0; i < size; i++) {for (int j = 0; j < size; j++) {System.out.print(board[i][j] + "\t");}System.out.println();}}public static void main(String[] args) {//棋盘的大小Scanner scanner =new Scanner(System.in);System.out.println("请输入棋盘的行列号:");int N = scanner.nextInt();System.out.println("请输入特殊方格的行号和列号:");int specialRow = scanner.nextInt();int specialCol = scanner.nextInt();ChessProblem chessProblem = new ChessProblem(specialRow , specialCol , N);System.out.println("输出原始棋盘");chessProblem.printBoard(specialRow, specialCol, N);System.out.println("输出覆盖棋盘");chessProblem.printBoard1(specialRow, specialCol, N);}
}
五、运行结果:
棋盘覆盖(Java)相关推荐
- 棋盘覆盖(java实现)
6.2 棋盘覆盖 1.问题描述 在一个2k×2k 个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘.在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给 ...
- JAVA大数_棋盘覆盖
第一道: 传送门:NYOJ 45 棋盘覆盖 2^k*2^k=4^k,其实就是大数计算,-1后取3的倍数.问题本源出自<计算机算法设计与分析>的棋盘覆盖问题,原始解法是分治法,递推出公式f( ...
- java棋盘问题_0x03大数问题(JAVA解决棋盘覆盖,A+B Problem II)
常见的有棋盘覆盖和A+B问题,这类问题牵扯到的数值都比较大,如果用一般的数值类型,肯定输出不了,所以就要想一个办法,怎么把大数转换一下输出. A+B Problem II 时间限制:3000 ms | ...
- 棋盘覆盖算法java_棋盘覆盖问题(算法分析)(Java版)
1.问题描述: 在一个2k×2k个方格组成的棋盘中,若有一个方格与其他方格不同,则称该方格为一特殊方格,且称该棋盘为一个特殊棋盘.显然特殊方格在棋盘上出现的位置有种情形.因而对任何 k≥0,有4k种不 ...
- 【Java】棋盘覆盖问题
棋盘覆盖问题抓住两点即可: 1.我们将一个大棋盘C分为四块,C的左上角是坐标是(0,0) 这个左上角坐标是用来区分在哪一个小棋盘的,抓住这个左上角的坐标变化 2.我们需要将没有特殊数字的其他三块继续分 ...
- java实现棋盘覆盖算法,java 棋盘覆盖算法
import java.util.Scanner; /** 棋盘覆盖 */ public class Arithmetic { /** 被覆盖后显示的数字,会根据覆盖的顺序有所递增 */ privat ...
- 【分治法】棋盘覆盖问题java实现
文章目录 问题描述 问题分析 算法设计 java代码 问题描述 在一个2k × 2k个放个中,恰好只有一个方格是残缺的.也就是在这个棋盘中有一个方格与其它的格子不同, 我们称这种棋盘为残缺棋盘. 下图 ...
- java棋盘覆盖_棋盘覆盖问题实现
[实例简介] 实现棋盘覆盖问题 [实例截图] [核心代码] public static void chessBoard(int dr, int dc, int tr, int tc, int size ...
- java棋盘覆盖分治法,棋盘覆盖-分治法
信 息 工 程 学 院 算法分析 实习报告 学院:信息工程学院 班级:软件工程083 姓名: 学号: 成绩: 一.实习题目 : 棋盘覆盖 二.实习过程 : 1.了解分治法的思想: 将一个难以解决的大问 ...
最新文章
- 发现“郝茵晴”:屌丝们的社会性传播实验
- 洛谷P1144-最短路计算【日常最短路,日常图论,SPFA】
- Lambda省略格式Lambda使用前提
- 05 hex 格式_SREC、Hex、Bin等烧录文件格式完全解读
- DJango周总结二:模型层,单表,多表操作,连表操作,数据库操作,事务
- python语法用到了什么_Python语法的使用和简介
- 百度Q2扭亏为盈 李彦宏发信勉励:变革带来阵痛 但能走得更稳更远
- ArcGIS Runtime SDK for Android 100开发环境部署
- java集中常见的算法讲解
- java poi Excel加密文件导出和下载
- 【iOS】 app 的优化
- [ 网络协议篇 ] IGP 详解之 OSPF 详解(一)--- 基础知识
- Android学习笔记(4)——探究碎片
- 中国大数据分析行业研究报告
- win7用软激活后今天失效,解决办法
- 科技将把我们带向哪里
- 1秒消失 alert jquery_jquery 弹窗信息显示几秒后自动消失
- LCA(最近公共祖先)问题
- 行业分析-全球与中国特里坦水瓶市场现状及未来发展趋势
- 数据sqlite 矢量切片_矢量切片(Vector tile)