一、分治的基本思想

  将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。

  对于一个规模为 n 的问题,若问题可以容易地解决,则直接解决,否则将其分解为 k 个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。

二、用分治法求解问题的主要步骤

  1、分解:将原问题分解为若干规模较小、相互独立、与原问题形式相同的子问题;

  2、解决:若子问题规模较小而容易被解决则直接解决,否则,递归地解各个子问题;

  3、合并:将各子问题的解合并得到原问题的解。

三、分治法实例

  1、棋盘覆盖

  在一个 2k * 2个方格组成的棋盘中,有一个方格与其它的不同,若使用以下四种 L 型骨牌覆盖除这个特殊方格的其它方格,如何覆盖。四个 L 型骨牌如下图:

图1.1 L型骨牌

棋盘中的特殊方格如图:

图1.2 存在特殊方格的棋盘
  覆盖完成后的棋盘:
图1.3 覆盖完成的棋盘
 #include<iostream>
using namespace std; int tile = ;
int Board[][]; //棋盘 /*
tr:棋盘左上角方格的行号
tc:棋盘左上角方格的列号
dr:特殊方格所在的行号
dc:特殊方格所在的列号
size:棋盘的规格(size * size)
*/
void ChessBoard(int tr,int tc , int dr, int dc, int size)
{
if(size == ) return;
int t =tile++, //L型骨牌号
s = size/; //分割棋盘
//覆盖左上角子棋盘
if(dr < tr+s && dc < tc+s)
//特殊方格在此棋盘中
ChessBoard(tr,tc,dr,dc,s);
else
{ //此棋盘中无特殊方格
//用t号L型骨牌覆盖右下角
Board[tr+s-][tc+s-] = t;
//覆盖其余方格
ChessBoard(tr,tc,dr,dc,s);
} //覆盖右上角子棋盘
if(dr < tr+s && dc >= tc+s)
//特殊方格在此棋盘中
ChessBoard(tr,tc+s,dr,dc,s);
else
{ //此棋盘中无特殊方格
//用t号L型骨牌覆盖左下角
Board[tr+s-][tc+s] = t;
//覆盖其余方格
ChessBoard(tr,tc+s,tr+s-,tc+s,s);
} //覆盖左下角子棋盘
if(dr >= tr+s && dc < tc+s)
//特殊方格在此棋盘中
ChessBoard(tr+s,tc,dr,dc,s);
else
{ //此棋盘中无特殊方格
//用t号L型骨牌覆盖右上角
Board[tr+s][tc+s-] = t;
//覆盖其余方格
ChessBoard(tr+s,tc,tr+s,tc+s-,s);
} //覆盖右下角子棋盘
if(dr >= tr+s && dc >= tc+s)
//特殊方格在此棋盘中
ChessBoard(tr+s,tc+s,dr,dc,s);
else
{ //此棋盘中无特殊方格
//用t号L型骨牌覆盖左上角
Board[tr+s][tc+s] = t;
//覆盖其余方格
ChessBoard(tr+s,tc+s,tr+s,tc+s,s);
} } int main()
{
ChessBoard( , , , , );
//输出覆盖完成后的棋盘
for(int i = ; i < ; i++)
{
for(int j = ; j < ; j++)
{
cout<<Board[i][j];
}
cout<<endl;
}
return ;
}

  2、循环赛日程表

  设有 n = 2个运动员要进行网球循环赛。现要设计一个满足以下要求的比赛日程表:

    (1)每个选手必须与其他n-1个选手各赛一次;

    (2)每个选手一天只能参赛一次;

    (3)循环赛在n-1天内结束

请按此要求将比赛日程表设计成有 n 行和 n-1 列的一个表。在表中的第 i 行,第 j 列处填入第 i 个选手在第 j 天所遇到的选手。其中 1 ≤ i ≤ n,1 ≤ j ≤ n-1。8 个选手的比赛日程表如下图:

 #include<iostream>
using namespace std; int a[][];
int n; //选手的个数 /*
tox:目标数组的行号
toy:目标数组的列号
fromx:源数组的行号
fromy:源数组的列号
r:数组的大小为 r*r
*/
void Copy(int tox, int toy, int fromx, int fromy, int r)
{
for(int i = ; i < r; i++)
for(int j = ; j < r; j++)
a[tox+i][toy+j] = a[fromx+i][fromy+j];
} void Table(int k)
{
n = << k;
//构造正方形表格的第一行数据
for(int i = ; i < n; i++)
a[][i] = i + ;
//采用分治算法,构造整个循环赛日程表
for(int r = ; r < n; r <<= )
for(int i = ; i < n; i += *r)
{
Copy(r, r + i, , i, r); //左上角复制到右下角
Copy(r, i, , r + i, r); //右上角复制到左下角
}
} int main()
{
int k;
cout<<"请输入k的值:";
cin>>k; Table(k); for(int i = ; i < n; i++)
{
for(int j = ; j < n; j++)
{
cout<< a[i][j] << " ";
}
cout<<endl;
}
return ;
}

[C++] 分治法之棋盘覆盖、循环赛日程表的更多相关文章

  1. js算法:分治法-棋盘覆盖

    在一个 2^k * 2^k 个方格组成的棋盘中,若恰有一个方格与其他方格不同.则称该方格为一特殊方格,称该棋盘为一特殊棋盘.显然特殊方格在棋盘上出现的位置有 4^k 种情形.因而对不论什么 k> ...

  2. js算法:分治法-循环赛事日程表

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...

  3. 分治法 - Divide and Conquer

    在计算机科学中,分治法是一种很重要的算法.分治法即『分而治之』,把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的 ...

  4. Java算法——分治法

         一.基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简 ...

  5. bzoj 2706: [SDOI2012]棋盘覆盖 Dancing Link

    2706: [SDOI2012]棋盘覆盖 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 255  Solved: 77[Submit][Status] ...

  6. 递归与分治策略之棋盘覆盖Java实现

    递归与分治策略之棋盘覆盖 一.问题描述 二.过程详解 1.棋盘如下图,其中有一特殊方格:16*16 . 2.第一个分割结果:8*8 3.第二次分割结果:4*4 4.第三次分割结果:2*2 5.第四次分 ...

  7. 棋盘覆盖问题python3实现

    在2^k*2^k个方格组成的棋盘中,有一个方格被占用,用下图的4种L型骨牌覆盖全部棋盘上的其余全部方格,不能重叠. 代码例如以下: def chess(tr,tc,pr,pc,size): globa ...

  8. 用python代码编写象棋界面,棋盘覆盖问题

    编写象棋界面 import turtle t=turtle.Pen() t.speed(100) def angle(x,y): t.penup() t.goto(x+3,y+3) t.pendown ...

  9. Python3解决棋盘覆盖问题的方法示例

    本文实例讲述了Python3解决棋盘覆盖问题的方法.分享给大家供大家参考,具体如下: 问题描述: 在2^k*2^k个方格组成的棋盘中,有一个方格被占用,用下图的4种L型骨牌覆盖所有棋盘上的其余所有方格 ...

随机推荐

  1. INSPIRED启示录 读书笔记 - 第40章 最佳实践经验

    十大要点 1.产品管理的职责:许多产品经理将大把的时间浪费在与产品管理无关的工作上 2.用户体验:对于大多数软件产品来说,用户体验就是产品的生命 3.机会评估:用方便快捷的机会评估方法取代过时的市场需 ...

  2. Go sync模块

    // A WaitGroup waits for a collection of goroutines to finish.// The main goroutine calls Add to set ...

  3. Go struct tag

    struct成员变量标签(Tag)说明 要比较详细的了解这个,要先了解一下golang的基础,在golang中,命名都是推荐都是用驼峰方式,并且在首字母大小写有特殊的语法含义:包外无法引用.但是由经常 ...

  4. 如何隐藏tomcat命令窗口

    有两种方法: 一.修改tomcat中的文件参数,达到隐藏目的: 引用:TOMCAT_HOME\bin\setclasspath.bat 在文件的底部找到以下内容: set _RUNJAVA=" ...

  5. Centos7 docker容器 搭建

    Dockerfile 文件如下: # # MAINTAINER Carson,C.J.Zeong <zcy@nicescale.com> # DOCKER-VERSION # # Dock ...

  6. linux基础(6)-shell编程

    shell脚本 shell脚本程序:以文件形式存放批量的linux命令集合,该文件能够被shell释放执行.通常由一段linux命令.shell命令.控制语句以及注释语句构成. shell脚本特点: ...

  7. DL四(预处理:主成分分析与白化 Preprocessing PCA and Whitening )

    预处理:主成分分析与白化 Preprocessing:PCA and Whitening 一主成分分析 PCA 1.1 基本术语 主成分分析 Principal Components Analysis ...

  8. 可编辑的div模仿文本框缓存(使用AUTOCOMPLETE属性,off是不缓存,on是缓存(默认))

    用session实现的, 1.进当前页面就从session(a)中取( sessionStorage.getItem )(不管存在不存在,后续有合理的存储和删除); 2.离开当前页时删除这个sessi ...

  9. Java中初始变量默认值

    Java语言中有8种基本数据类型,基本情况汇总如下: 序号 数据类型 大小/位 封装类 默认值 可表示数据范围 1 byte(位) 8 Byte 0 -128~127 2 short(短整数) 16 ...

  10. The type java.io.ObjectInputStream cannot be resolved. It is indirectly referenced from required .class files

    要解决的话,方法有两个 1)可以选用较低版本的sdk,比如我就用回1.6版本的sdk window->preferences->Java->Installed JREs->Ad ...