【算法复习二】传统基本算法(分治----残缺棋盘问题)

2024-04-05 01:58

本文主要是介绍【算法复习二】传统基本算法(分治----残缺棋盘问题),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  问题描述:

  残缺棋盘是一个有2k×2kk≥1)个方格的棋盘,其中恰有一个方格残缺。如图给出k=1时各种可能的残缺棋盘,其中残缺的方格用阴影表示。

残缺棋盘问题就是要用这四种三格板覆盖更大的残缺棋盘。在此覆盖中要求:

        1)两个三格板不能重叠

        2)三格板不能覆盖残缺方格,但必须覆盖其他所有的方格。

         

         小格子数(2k×2k -1)三格板中小格子数3。所以所需要的三格板总数为(2k×2k -1 )/3

  例如,一个4*4的残缺棋盘2k*2k

        以k=2时的问题为例,用二分法进行分解,得到的四个k=1的棋盘。但要注意这四个棋盘,并不都是与原问题相似且独立的子问题。

        因为当如图中的残缺方格在左上部时,第1个子问题与原问题相似,而右上角、左下角和右下角三个子棋盘(也就是图中标识为234号子棋盘),并不是原问题的相似子问题,自然也就不能独立求解了。当使用一个①号三格板覆盖234号三个子棋盘的各一个方格后,我们把覆盖后的方格,也看作是残缺方格(称为残缺方格),这时的234号子问题就是独立且与原问题相似的子问题了。

  问题分析

           从以上例子还可以发现

               当残缺方格在第1个子棋盘,用①号三格板覆盖其余三个子棋盘的交界方格,可以使另外三个子棋盘转化为独立子问题;

               当残缺方格在第2个子棋盘时,则首先用②号三格板进行棋盘覆盖

               当残缺方格在第3个子棋盘时,则首先用③号三格板进行棋盘覆盖

               当残缺方格在第4个子棋盘时,则首先用④号三格板进行棋盘覆盖,这样就使另外三个子棋盘转化为独立子问题。

程序代码思路:

         表示方法:每个三格板需要用同一个数字表示,不同三格板编号不同。

源码:

#include <iostream>
#include <iomanip>
using namespace std;
int board[100][100];  //存放棋盘L型的标号数组;
int tile=1;    // L型骨牌号
void chessBoard(int tr, int tc, int dr, int dc, int size)
{ 
if (size==1)
return;
int t = tile++;     // L型骨牌号
int s = size/2;     // 分割棋盘
//________________________________________________ 覆盖左上角子棋盘
if (dr<tr+s&&dc<tc+s)     // 特殊方格在此棋盘中
chessBoard(tr, tc, dr, dc, s);
else                               // 此棋盘中无特殊方格
{           
board[tr+s-1][tc+s-1]=t; // 用 t 号L型骨牌覆盖右下角
chessBoard(tr,tc,tr+s-1, tc+s-1, s);// 覆盖其余方格
} 
//________________________________________________ 覆盖右上角子棋盘
if (dr < tr + s && dc >= tc + s)     // 特殊方格在此棋盘中
chessBoard(tr, tc+s, dr, dc, s);
else                                  // 此棋盘中无特殊方格
{
board[tr + s - 1][tc + s] = t;   //用t号L型骨牌覆盖左下角
chessBoard(tr, tc+s, tr+s-1, tc+s, s);// 覆盖其余方格
}
//_______________________________________________ 覆盖左下角子棋盘
if (dr >= tr + s && dc < tc + s)  // 特殊方格在此棋盘中
chessBoard(tr+s, tc, dr, dc, s);
else                               // 此棋盘中无特殊方格                       
{
board[tr + s][tc + s - 1] = t;  // 用 t 号L型骨牌覆盖右上角
chessBoard(tr+s, tc, tr+s, tc+s-1, s);// 覆盖其余方格
} 
//__________________________________________________ 覆盖右下角子棋盘
if (dr >= tr + s && dc >= tc + s)  // 特殊方格在此棋盘中
chessBoard(tr+s, tc+s, dr, dc, s);
else 
{
board[tr + s][tc + s] = t;     // 用 t 号L型骨牌覆盖左上角       
chessBoard(tr+s, tc+s, tr+s, tc+s, s); // 覆盖其余方格
}
}
int main()
{
int size,dr,dc;
cout<<"\t\t\t棋盘覆盖问题\n";
cout<<"2^k×2^k 个方格变长size(size=2,4,8,16,32,64):";
cin>>size;
cout<<"分别输入特殊块的行下标dr,列下标dc(0-"<<(size-1)<<"):";
cin>>dr>>dc;
board[dr][dc]=0;
cout<<"棋盘覆盖图:\n";
chessBoard(0, 0, dr, dc, size);
int i,j;
for( i=0;i<size;i++)
{
for( j=0;j<size;j++)
cout<<setw(6)<<board[i][j];//setw(6)//输出量不足6个字符时在左面填充空白 
cout<<endl<<endl;
}
return 0;
}


分治递归执行步骤:

         1)chessBoard(0, 0, 0, 0, 4);

               {          t=1;   s=2;

                        chessBoard(0, 0, 0, 0, 2);

                            {        t=2; s=1;

                                     chessBoard(0, 0, 0, 0, 1);

                                          {          s==1

                                                       return  

                                          }

                                                       以下三步

                                                        将左上角 三格板 用t=2覆盖

                               }

                              return

                                      以下三步 对右上递归  先 用t=1 覆盖左下

                                                          左下递归 先 用t=1 覆盖右上

                                                          右下递归 先 用t=1 覆盖左上

                                      递归处理类似。

                  }

                                    

这篇关于【算法复习二】传统基本算法(分治----残缺棋盘问题)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/877378

相关文章

解决pandas无法读取csv文件数据的问题

《解决pandas无法读取csv文件数据的问题》本文讲述作者用Pandas读取CSV文件时因参数设置不当导致数据错位,通过调整delimiter和on_bad_lines参数最终解决问题,并强调正确参... 目录一、前言二、问题复现1. 问题2. 通过 on_bad_lines=‘warn’ 跳过异常数据3

解决RocketMQ的幂等性问题

《解决RocketMQ的幂等性问题》重复消费因调用链路长、消息发送超时或消费者故障导致,通过生产者消息查询、Redis缓存及消费者唯一主键可以确保幂等性,避免重复处理,本文主要介绍了解决RocketM... 目录造成重复消费的原因解决方法生产者端消费者端代码实现造成重复消费的原因当系统的调用链路比较长的时

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499

kkFileView启动报错:报错2003端口占用的问题及解决

《kkFileView启动报错:报错2003端口占用的问题及解决》kkFileView启动报错因office组件2003端口未关闭,解决:查杀占用端口的进程,终止Java进程,使用shutdown.s... 目录原因解决总结kkFileViewjavascript启动报错启动office组件失败,请检查of

SpringBoot 异常处理/自定义格式校验的问题实例详解

《SpringBoot异常处理/自定义格式校验的问题实例详解》文章探讨SpringBoot中自定义注解校验问题,区分参数级与类级约束触发的异常类型,建议通过@RestControllerAdvice... 目录1. 问题简要描述2. 异常触发1) 参数级别约束2) 类级别约束3. 异常处理1) 字段级别约束

详解MySQL中JSON数据类型用法及与传统JSON字符串对比

《详解MySQL中JSON数据类型用法及与传统JSON字符串对比》MySQL从5.7版本开始引入了JSON数据类型,专门用于存储JSON格式的数据,本文将为大家简单介绍一下MySQL中JSON数据类型... 目录前言基本用法jsON数据类型 vs 传统JSON字符串1. 存储方式2. 查询方式对比3. 索引

Python错误AttributeError: 'NoneType' object has no attribute问题的彻底解决方法

《Python错误AttributeError:NoneTypeobjecthasnoattribute问题的彻底解决方法》在Python项目开发和调试过程中,经常会碰到这样一个异常信息... 目录问题背景与概述错误解读:AttributeError: 'NoneType' object has no at

Spring的RedisTemplate的json反序列泛型丢失问题解决

《Spring的RedisTemplate的json反序列泛型丢失问题解决》本文主要介绍了SpringRedisTemplate中使用JSON序列化时泛型信息丢失的问题及其提出三种解决方案,可以根据性... 目录背景解决方案方案一方案二方案三总结背景在使用RedisTemplate操作redis时我们针对

Kotlin Map映射转换问题小结

《KotlinMap映射转换问题小结》文章介绍了Kotlin集合转换的多种方法,包括map(一对一转换)、mapIndexed(带索引)、mapNotNull(过滤null)、mapKeys/map... 目录Kotlin 集合转换:map、mapIndexed、mapNotNull、mapKeys、map

nginx中端口无权限的问题解决

《nginx中端口无权限的问题解决》当Nginx日志报错bind()to80failed(13:Permissiondenied)时,这通常是由于权限不足导致Nginx无法绑定到80端口,下面就来... 目录一、问题原因分析二、解决方案1. 以 root 权限运行 Nginx(不推荐)2. 为 Nginx