棋盘覆盖(java实现)
棋盘覆盖
问题描述
在一个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.每次都对分割后的四个小棋盘进行判断,判断特殊方格是否在里面。
这里的判断的方法是每次先记录下整个大棋盘的左上角方格的行列坐标,然后再与特殊方格坐标进行比较,就可以知道特殊方格是否在该块棋盘中。
- 如果特殊方块在里面,这直接递归下去求即可,
- 如果不在,这根据分割的四个棋盘的不同位置,把右下角、左下角、右上角或者左上角的方格标记为特殊方块,然后继续递归。在递归函数里,还要有一个变量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.递归的结束条件
- size为1时
//大小为1时,结束递归
if (1 == size) {
return;
}
- 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实现)的更多相关文章
- 递归与分治策略之棋盘覆盖Java实现
递归与分治策略之棋盘覆盖 一.问题描述 二.过程详解 1.棋盘如下图,其中有一特殊方格:16*16 . 2.第一个分割结果:8*8 3.第二次分割结果:4*4 4.第三次分割结果:2*2 5.第四次分 ...
- 棋盘覆盖(大数阶乘,大数相除 + java)
棋盘覆盖 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 在一个2k×2k(1<=k<=100)的棋盘中恰有一方格被覆盖,如图1(k=2时),现用一缺角的 ...
- 棋盘覆盖问题(算法分析)(Java版)
1.问题描述: 在一个2k×2k个方格组成的棋盘中,若有一个方格与其他方格不同,则称该方格为一特殊方格,且称该棋盘为一个特殊棋盘.显然特殊方格在棋盘上出现的位置有种情形.因而对任何 k≥0,有4k种不 ...
- NYOJ 45 棋盘覆盖
棋盘覆盖 水题,题不难,找公式难 import java.math.BigInteger; import java.util.Scanner; public class Main { public s ...
- bzoj 2706: [SDOI2012]棋盘覆盖 Dancing Link
2706: [SDOI2012]棋盘覆盖 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 255 Solved: 77[Submit][Status] ...
- NYOJ 45 棋盘覆盖 模拟+高精度
题意就不说了,中文题... 小白上讲了棋盘覆盖,于是我就挖了这题来做. 棋盘覆盖的推导不是很难理解,就是分治的思想,具体可以去谷歌下. 公式就是f(k) = f(k - 1) * 4 + 1,再化解下 ...
- 棋盘覆盖(一) ACM
棋盘覆盖 描述 在一个2k×2k(1<=k<=100)的棋盘中恰有一方格被覆盖,如图1(k=2时),现用一缺角的2×2方格(图2为其中缺右下角的一个),去覆盖2k×2k未被覆盖过的方格,求 ...
- CODEVS 2171 棋盘覆盖
2171 棋盘覆盖 给出一张nn(n<=100)的国际象棋棋盘,其中被删除了一些点,问可以使用多少12的多米诺骨牌进行掩盖. 错误日志: 直接在模板上调整 \(maxn\) 时没有在相应邻接表数 ...
- JavaScript编写棋盘覆盖
一.前言 之前做了一个算法作业,叫做棋盘覆盖,本来需要用c语言来编写的,但是因为我的c语言是半桶水(哈哈),所以索性就把网上的c语言写法改成JavaScript写法,并且把它的覆盖效果显示出来 二.关 ...
- TYVJ 1035 / codevs 2171 棋盘覆盖
Problem Description 给定一个n * m的棋盘,已知某些各自禁止放置,求最多往棋盘上放多少长度为2宽度为1的骨牌(骨牌不重叠) Input 第一行为n,m(表示有m个删除的格子)第二 ...
随机推荐
- Group 和 Distinct 列的次序影响查询性能
目录 一.概述 二.work_mem 满足排序情况 1.Distinct 语句 2.Group by 语句 三.work_mem 不满足排序情况 1.Distinct 语句 2.Group by 语句 ...
- Hadoop阶段学习总结
第一部分:HDFS相关问题 一.描述一下HDFS的数据写入流程 首先由客户端想NameNode服务发起写数据请求,NameNode接收到请求后会进行基本验证,验证内容包括对请求上传的路径进行合法验 ...
- 2020年12月-第02阶段-前端基础-CSS Day06
CSS Day06 定位(position) 理解 能说出为什么要用定位 能说出定位的4种分类 能说出四种定位的各自特点 能说出我们为什么常用子绝父相布局 应用 能写出淘宝轮播图布局 1. CSS 布 ...
- frp内网穿透实战
什么是frp frp是一个使用非常简单的开源内网穿透软件,代码地址:https://github.com/fatedier/frp ,使用条前提你需要有一台公网服务器,大致原理是:公网服务器监听某个端 ...
- 面试说:聊聊JavaScript中的数据类型
前言 请讲下 JavaScript 中的数据类型? 前端面试中,估计大家都被这么问过. 答:Javascript 中的数据类型包括原始类型和引用类型.其中原始类型包括 null.undefined.b ...
- Kubernetes DevOps: Gitlab
Gitlab 官方提供了 Helm 的方式在 Kubernetes 集群中来快速安装,但是在使用的过程中发现 Helm 提供的 Chart 包中有很多其他额外的配置,所以我们这里使用自定义的方式来安装 ...
- Solutions:Elastic SIEM - 适用于家庭和企业的安全防护 ( 二)
- [题解] Atcoder ARC 142 E Pairing Wizards 最小割
题目 建图很妙,不会. 考虑每一对要求合法的巫师(x,y),他们两个的\(a\)必须都大于\(min(b_x,b_y)\).所以在输入的时候,如果\(a_x\)或者\(a_y\)小于\(min(b_x ...
- 玩转Google开源C++单元测试框架Google Test系列(gtest)之八 - 打造自己的单元测试框架
转载来源:https://www.cnblogs.com/coderzh/archive/2009/04/12/1434155.html 一.前言 上一篇我们分析了gtest的一些内部实现,总的来说整 ...
- Mapper 实体转换Entiy to Dto
实际使用中发现很多问题 如果用EFcore 框架,这个表达式树生成一个新的实体导致EFcore 跟踪失败!/// <summary> /// 生成表达式目录树 泛型缓存 /// </ ...