[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型骨牌覆盖所有棋盘上的其余所有方格 ...
 
随机推荐
- linux下查找文件或目录(which,whereis,locate,find)
			
命令 查找对象 查找速度 备注 which 可执行文件 根据PATH变量的内容去寻找可执行文件 不同的PATH配置会有不一样的结果 whereis 程序名的搜索 根据数据库来寻找,速度快 ...
 - 20145210姚思羽 《网络对抗技术》 Web安全基础实践
			
20145210姚思羽 <网络对抗技术> Web安全基础实践 实验后回答问题 1.SQL注入攻击原理,如何防御 ·SQL攻击的原理很简单,就是在用户名输入框里输入SQL语句,来欺骗数据库服 ...
 - cocos2dx打飞机项目笔记七:各种回调:定时器schedule、普通回调callFunc、菜单回调menu_selector、事件回调event_selector
			
各种回调函数的定义: typedef void (CCObject::*SEL_SCHEDULE)(float); typedef void (CCObject::*SEL_CallFunc)(); ...
 - 区间dp的感悟
			
学区间dp似乎也很久了...对区间dp的通用模型都了解了一些 但是做题还是很坑 上了一点难度的题基本想不出什么思路.. 目前的做题方式就是看题 想一会发现自己不会做 看题解 好巧妙啊 理解后写一发.. ...
 - BZOJ3242/UOJ126 [Noi2013]快餐店
			
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
 - RtlWerpReportException failed with status code :-1073741823
			
在release下程序运行总是崩溃:debugView输出了这个崩溃信息, 1. 一开始是release看崩溃,各种二分法找崩溃点,太玄没找到: 2. 终于想到可以调试,我草,调试一下瞬间发现某个cl ...
 - hibernate学习(2)
			
1 实体类编写规则 2 hibernate主键生成策略 3实体类操作 (1)crud操作 (2)实体对象状态 4 hibernate的一级缓存 5 hibernate事务操作 (1)事务代码规则写法 ...
 - centos ifcfg-eth0
			
DEVICE=eth0IPADDR=192.168.1.117NETMASK=255.255.255.0GATEWAY=192.168.1.1ONBOOT=yes
 - leetcode 645. Set Mismatch——凡是要节约空间的题目 都在输入数据上下功夫 不要担心破坏原始的input
			
The set S originally contains numbers from 1 to n. But unfortunately, due to the data error, one of ...
 - ionic2——环境配置篇
			
环境配置 安装nodeJS 配置cnpm 安装ionic2 安装cordova 安装java sdk 安装android sdk(在项目最后打包时app的时候会用到,前期是在浏览器环境测试开发暂时不需 ...