棋盘覆盖

问题描述

在一个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. JavaScript之数组常用API

    这篇文章主要帮助大家简单理解数组的一些常用API用法,许多小伙伴常用方法记不住?别急,看完下面的介绍您一定就会明白各个方法是如何用的了.该文章适合新手小白看,大佬可以多多指点️! 1.数组的创建以及A ...

  2. 记一次 Sedona(GeoSpark) 空间计算优化

    项目需求需要空间计算能力,开始选型Sedona(GeoSpark)来完成, 需求需要每一条数据在满足某条件的情况下,去查找某张表进行空间匹配,找到离这个点(point)最近的一条道路(lineStri ...

  3. 对表白墙js文件的解释

    index.js 1 Page({ 2 3 /** 4 * 页面的初始数据 5 */ 6 data: { 7 xcx_appid:"", 8 }, 9 HuoquDaohangLi ...

  4. 【Tool】Idea快捷键

    Windows Ctrl + F12: 查找当前类中的方法 Ctrl + N: 查找类 Ctrl + Alt + H: 查看方法调用关系 Ctrl + H: 查看类的继承关系 Alt + F7:查找类 ...

  5. Traefik SRE 之使用 Prometheus 进行监控报警

    当我们使用 Traefik 作为 Kubernetes 的 Ingress 控制器的时候,我们自然也非常有必要对其进行监控.本文我们将探讨如何使用 Prometheus 和 Grafana 从 Tra ...

  6. Beats:使用Elastic Stack对Nginx Web服务器监控

  7. Kibana:如何让用户匿名访问 Kibana 中的 Dashboard

    文章转载自:https://elasticstack.blog.csdn.net/article/details/118152293 有一个很好的 Dashboard,我们想分析这个 Dashboar ...

  8. css语言

    css:样式表.级联样式表.层叠样式表 css写在style标签里面,放在head标签中:大括号中写键值对语法 color:文字颜色 Font-family:字体 Font-size:字号 text- ...

  9. Libgdx游戏学习(1)——环境配置及demo运行

    原文: Libgdx游戏学习(1)--环境配置及demo运行 - Stars-One的杂货小窝 Libgdx游戏是基于Java的一款游戏引擎,可以发布Android,桌面端,Html,IOS等游戏,出 ...

  10. SpringBoot(一) - SpringBoot 初识

    1.创建SpringBoot项目 1.1 使用Spring Initializr 的 Web页面创建项目 创建网址:https://start.spring.io/ 1.2 使用IDEA创建 省略: ...