一、分治的基本思想

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

  对于一个规模为 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. blast+学习之search tools

    search tools:blastn, blastp, blastx, tblastx, tblastn, psiblast, rpsblast, and rpstblastn 1.blastn: ...

  2. codeforces上某题

    一道codeforces上的题目. 题目大意: 定义有k个不同的字符的字符串为好字符串.现在给出一个字符串,求解对该字符串的每个前缀Si至少是多少个好字符串的连接,若不能由好字符串连接而成则输出-1. ...

  3. 20145230《java程序设计》第三次试验报告

    20145208 实验三 Java面向对象程序设计 实验内容 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模 ...

  4. Qt构造函数的参数:QObject *parent = Q_NULLPTR

    几乎所有的Qt类的构造函数都会有一个parent参数.这个参数通常是QObject* 或者是 QWidget* 类型的.很多情况下它都会有一个初始值0,因此,即便你不去给它复制也没有丝毫的问题.于是, ...

  5. [Python] 弗洛伊德(Floyd)算法求图的直径并记录路径

    相关概念 对于一个图G=(V, E),求图中两点u, v间最短路径长度,称为图的最短路径问题.最短路径中最长的称为图的直径. 其中,求图中确定的某两点的最短路径算法,称为单源最短路径算法.求图中任意两 ...

  6. JAVAWeb学习总结(3)

    JavaWeb学习总结(三)——Tomcat服务器学习和使用(二) 一.打包JavaWeb应用 在Java中,使用"jar"命令来对将JavaWeb应用打包成一个War包,jar命 ...

  7. Kafka详解一:Kafka简介

    问题导读 1.Kafka有何特性?2.Kafka有哪些组件? 背景:     当今社会各种应用系统诸如商业.社交.搜索.浏览等像信息工厂一样不断的生产出各种信息,在大数据时代,我们面临如下几个挑战: ...

  8. dede数据库表结构和dedecms数据库字段说明

    表名:dede_addonarticle (ENGINE=MyISAM/CHARSET=gbk) 说明:Top 字段名 说明描述 具体参数 aid 文章ID mediumint(8) unsigned ...

  9. Canvas - Web API

    <canvas> 是 HTML5 新增的元素,可用于通过使用JavaScript中的脚本来绘制图形.例如,它可以用于绘制图形,制作照片,创建动画,甚至可以进行实时视频处理或渲染. Mozi ...

  10. Windows7 如何关闭系统更新

    我们点击开始菜单,找到控制面板这个选项,如图:  然后进入操作中心,如图:  然后选择如图所示的选项,如图:  然后选择更改设置选项,如图:  然后我们选择从不检查更新并点击确定按钮,如图: