java 实现棋盘覆盖问题
时间:2022-05-04
本文章向大家介绍java 实现棋盘覆盖问题,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
- 问题描述:在一个2k*2k的棋盘中,有一个特殊方格,要求用L型骨牌覆盖满除特殊方格外的所有其他方格,且骨牌不得重叠.(骨牌可以旋转放置)
- 输入:棋盘的边长、特殊方格坐标
- 输出:骨牌放法.其中用0表示特殊方格,同一张骨牌所占方格用同一个数字表示,不同骨牌用不同数字.
解题思想:
采用分治法解决该问题。分治法是把一个规模很大的问题分解为多个规模较小、类似的子问题,然后递归地解决所有子问题,最后再由子问题的解决得到原问题的解决。
所以将2k*2k的棋盘,先分成相等的四块子棋盘,其中特殊方格位于四个中的一个,构造剩下没特殊方格三个子棋盘:将一块骨牌放在这三个小棋盘的交界处,使骨牌的每一个方格都作为三个小棋盘的特殊方格,骨牌具体放法如下:
- 左上的子棋盘若不存在特殊方格,将该子棋盘右下角的那个方格覆盖为特殊方格
- 右上的子棋盘若不存在特殊方格,将该子棋盘左下角的那个方格覆盖为特殊方格
- 左下的子棋盘若不存在特殊方格,将该子棋盘右上角的那个方格覆盖为特殊方格
- 右下的子棋盘若不存在特殊方格,将该子棋盘左上角的那个方格覆盖为特殊方格 至此,每个小棋盘都有一个特殊方格,然后递归调用,就可以解决问题了。
public class Chess {
/** 棋盘的规格 */
public static int SIZE = 8;
/** 特殊格子的竖坐标(从零开始) */
public static int TR = 1;
/** 特殊格子的横坐标(从零开始) */
public static int TC = 1;
/** 模拟棋盘 */
static int[][] board;
/** 模拟骨牌(相同数字为同一块骨牌) */
static int tile = 1;
/**
* 棋盘覆盖问题
* @param dr 左上角方格行号
* @param dc 左上角方格列号
* @param tr 特殊方格行号
* @param tc 特殊方格列号
* @param size 2的正整数次方
*/
public static void chessBoard(int dr, int dc, int tr, int tc, int size) {
if (size == 1) {
return;
}
int t = tile++;
/** 分割棋盘后的size */
int s = size / 2;
// 判断特殊方格是否在左上角的小棋盘中
if (tr < dr + s && tc < dc + s) {
chessBoard(dr, dc, tr, tc, s);
} else {
board[dr + s - 1][dc + s - 1] = t;
chessBoard(dr, dc, dr + s - 1, dc + s - 1, s);
}
// 判断特殊方格是否在右上角的小棋盘中
if (tr < dr + s && tc >= dc + s) {
chessBoard(dr, dc + s, tr, tc, s);
} else {
board[dr + s - 1][dc + s] = t;
chessBoard(dr, dc + s, dr + s - 1, dc + s, s);
}
// 判断特殊方格是否在左下角的小棋盘中
if (tr >= dr + s && tc < dc + s) {
chessBoard(dr + s, dc, tr, tc, s);
} else {
board[dr + s][dc + s - 1] = t;
chessBoard(dr + s, dc, dr + s, dc + s - 1, s);
}
// 判断特殊方格是否在youxia角的小棋盘中
if (tr >= dr + s && tc >= dc + s) {
chessBoard(dr + s, dc + s, tr, tc, s);
} else {
board[dr + s][dc + s] = t;
chessBoard(dr + s, dc + s, dr + s, dc + s, s);
}
}
public static void main(String[] args) {
// init parameter
try{
if(args[0]!=null){
SIZE = Integer.parseInt(args[0], 10);
}
if(args[1]!=null){
TR = Integer.parseInt(args[1], 10);
}
if(args[2]!=null){
TC = Integer.parseInt(args[2], 10);
}
}catch(Exception e){
System.out.print("t(部分)采用默认参数");
}
System.out.printf("t棋盘规模:%d*%d",SIZE,SIZE);
System.out.printf("t特殊方格:(%d,%d)",TR,TC);
// 初始化棋盘
board = new int[SIZE][SIZE];
// 调用方法进行测试
chessBoard(0, 0, TR, TC, SIZE);
// 显示棋盘结果
for (int[] is : board) {
System.out.println();
for (int i : is) {
System.out.printf("%4d", i);
}
}
}
}
效果截图:
算法复杂性分析:
设T(k)是此算法所需的时间,则根据分治法可知:
解此递归方程可得,T(k)=O(4k)。由于覆盖2k*2k的棋盘所需的骨牌个数为(4k-1)/3,所以此算法是一个渐进意义下最优算法。
- 10种简单的Java性能优化学习
- 巧用枚举类型,实现项目的多语言切换
- 影响Java调用性能有哪些因素
- 如何为可扩展系统进行Java Socket编程
- 如何使用Windows卷影拷贝服务恢复文件和文件夹
- .net字符串数组查找方式效率比较
- 使用Ring Buffer构建高性能的文件写入程序
- 一行代码调用实现带字段选取+条件判断+排序+分页功能的增强ORM框架
- PDF.NET数据开发框架实体类操作实例
- 利用Burp Suite对OWASP Juice Shop进行渗透测试
- Java同步问题面试知识学习
- Android UI控件系列:LinearLayout(线性布局)
- 使用操作符重载,生成ORM实体类的SQL条件语句
- Dance In Heap(四):一些堆利用的方法(下)
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释