[C++] 分治法之棋盘覆盖、循环赛日程表
一、分治的基本思想
将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
对于一个规模为 n 的问题,若问题可以容易地解决,则直接解决,否则将其分解为 k 个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。
二、用分治法求解问题的主要步骤
1、分解:将原问题分解为若干规模较小、相互独立、与原问题形式相同的子问题;
2、解决:若子问题规模较小而容易被解决则直接解决,否则,递归地解各个子问题;
3、合并:将各子问题的解合并得到原问题的解。
三、分治法实例
1、棋盘覆盖
在一个 2k * 2k 个方格组成的棋盘中,有一个方格与其它的不同,若使用以下四种 L 型骨牌覆盖除这个特殊方格的其它方格,如何覆盖。四个 L 型骨牌如下图:
图1.1 L型骨牌
棋盘中的特殊方格如图:
#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 = 2k 个运动员要进行网球循环赛。现要设计一个满足以下要求的比赛日程表:
(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++] 分治法之棋盘覆盖、循环赛日程表的更多相关文章
- js算法:分治法-棋盘覆盖
在一个 2^k * 2^k 个方格组成的棋盘中,若恰有一个方格与其他方格不同.则称该方格为一特殊方格,称该棋盘为一特殊棋盘.显然特殊方格在棋盘上出现的位置有 4^k 种情形.因而对不论什么 k> ...
- js算法:分治法-循环赛事日程表
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...
- 分治法 - Divide and Conquer
在计算机科学中,分治法是一种很重要的算法.分治法即『分而治之』,把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的 ...
- Java算法——分治法
一.基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简 ...
- bzoj 2706: [SDOI2012]棋盘覆盖 Dancing Link
2706: [SDOI2012]棋盘覆盖 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 255 Solved: 77[Submit][Status] ...
- 递归与分治策略之棋盘覆盖Java实现
递归与分治策略之棋盘覆盖 一.问题描述 二.过程详解 1.棋盘如下图,其中有一特殊方格:16*16 . 2.第一个分割结果:8*8 3.第二次分割结果:4*4 4.第三次分割结果:2*2 5.第四次分 ...
- 棋盘覆盖问题python3实现
在2^k*2^k个方格组成的棋盘中,有一个方格被占用,用下图的4种L型骨牌覆盖全部棋盘上的其余全部方格,不能重叠. 代码例如以下: def chess(tr,tc,pr,pc,size): globa ...
- 用python代码编写象棋界面,棋盘覆盖问题
编写象棋界面 import turtle t=turtle.Pen() t.speed(100) def angle(x,y): t.penup() t.goto(x+3,y+3) t.pendown ...
- Python3解决棋盘覆盖问题的方法示例
本文实例讲述了Python3解决棋盘覆盖问题的方法.分享给大家供大家参考,具体如下: 问题描述: 在2^k*2^k个方格组成的棋盘中,有一个方格被占用,用下图的4种L型骨牌覆盖所有棋盘上的其余所有方格 ...
随机推荐
- 大话设计模式之PHP篇 - 观察者模式
定义观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生改变时,会通知所有观察者对象,使他们能够自动更新自己. <?php /*主题类或称为通知类 ...
- 一个gpio 不受控制的bug
前几天调试一个flash灯的驱动程序,这可ic 有两个控制pin, 一个叫en1 一个叫en2, 根据spec的说明,不同的组合将产生不同的输出电流.但我发现,那个en1 这个pin 死活是拉不高的, ...
- linux下pycharm的使用
百度搜索pycharm 然后打开pycharm的官网 然后在官网首页点击down 如果使用的是Linux系统,那么默认已经选择Linux版本 左边的down是全功能的IDE和WEB扩展,属于商业版 ...
- HBase-存储-HFile格式
HBase-存储-HFile格式 实际的存储文件功能是由HFile类实现的,它被专门创建以达到一个目的:有效地存储HBase的数据.它们基于Hadoop的TFile类,并模仿Google的BigTab ...
- QT 文本html显示格式的问题,如在QTextBrowser.setText用tr(),其中为html格式
QObject::tr("<h1><font color = green>%1</font>的人品指数:<font color = orange&g ...
- MATLAB选出一个数组里n个元素的所有组合
用nchoosek(A,n) 如: nchoosek([1,5,3,2,4,0],3) nchoosek([1,5,3,2],2)ans = 1 5 1 3 1 ...
- Quartz实现定时任务实例
1首先实现Job接口,创建任务 public class HelloJob implements Job{ @Override public void execute(JobExecutionCont ...
- 解决没有referenced Libraries的方法
- Secret Code
Secret Code 一.题目 [NOIP模拟赛A10]Secret Code 时间限制: 1 Sec 内存限制: 128 MB 提交: 10 解决: 6 [提交][状态][讨论版] 题目描述 ...
- hdu4217splay
题意:有1到n的数组,每次删除第k小的值,并求和 题解:splay基本操作,删除+合并 坑点:由于不会c++指针操作,sb的只删除了头指针导致一直mle #include<bits/stdc++ ...