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

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

相关文章

C++中使用vector存储并遍历数据的基本步骤

《C++中使用vector存储并遍历数据的基本步骤》C++标准模板库(STL)提供了多种容器类型,包括顺序容器、关联容器、无序关联容器和容器适配器,每种容器都有其特定的用途和特性,:本文主要介绍C... 目录(1)容器及简要描述‌php顺序容器‌‌关联容器‌‌无序关联容器‌(基于哈希表):‌容器适配器‌:(

大数据小内存排序问题如何巧妙解决

《大数据小内存排序问题如何巧妙解决》文章介绍了大数据小内存排序的三种方法:数据库排序、分治法和位图法,数据库排序简单但速度慢,对设备要求高;分治法高效但实现复杂;位图法可读性差,但存储空间受限... 目录三种方法:方法概要数据库排序(http://www.chinasem.cn对数据库设备要求较高)分治法(常

Vue项目中Element UI组件未注册的问题原因及解决方法

《Vue项目中ElementUI组件未注册的问题原因及解决方法》在Vue项目中使用ElementUI组件库时,开发者可能会遇到一些常见问题,例如组件未正确注册导致的警告或错误,本文将详细探讨这些问题... 目录引言一、问题背景1.1 错误信息分析1.2 问题原因二、解决方法2.1 全局引入 Element

关于@MapperScan和@ComponentScan的使用问题

《关于@MapperScan和@ComponentScan的使用问题》文章介绍了在使用`@MapperScan`和`@ComponentScan`时可能会遇到的包扫描冲突问题,并提供了解决方法,同时,... 目录@MapperScan和@ComponentScan的使用问题报错如下原因解决办法课外拓展总结@

MybatisGenerator文件生成不出对应文件的问题

《MybatisGenerator文件生成不出对应文件的问题》本文介绍了使用MybatisGenerator生成文件时遇到的问题及解决方法,主要步骤包括检查目标表是否存在、是否能连接到数据库、配置生成... 目录MyBATisGenerator 文件生成不出对应文件先在项目结构里引入“targetProje

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

numpy求解线性代数相关问题

《numpy求解线性代数相关问题》本文主要介绍了numpy求解线性代数相关问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 在numpy中有numpy.array类型和numpy.mat类型,前者是数组类型,后者是矩阵类型。数组

使用Python进行文件读写操作的基本方法

《使用Python进行文件读写操作的基本方法》今天的内容来介绍Python中进行文件读写操作的方法,这在学习Python时是必不可少的技术点,希望可以帮助到正在学习python的小伙伴,以下是Pyth... 目录一、文件读取:二、文件写入:三、文件追加:四、文件读写的二进制模式:五、使用 json 模块读写

解决systemctl reload nginx重启Nginx服务报错:Job for nginx.service invalid问题

《解决systemctlreloadnginx重启Nginx服务报错:Jobfornginx.serviceinvalid问题》文章描述了通过`systemctlstatusnginx.se... 目录systemctl reload nginx重启Nginx服务报错:Job for nginx.javas