[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型骨牌覆盖所有棋盘上的其余所有方格 ...
随机推荐
- Maven——安装配置
MAVEN 一.介绍:(待填) 二.下载:http://maven.apache.org/download.cgi(官网下载) 选择二进制的zip文件,这种的可直接使用. 三.环境配置 1.前提条件: ...
- Thinkpad个性化设置:F1~F12恢复正常按键,Fn与Ctrl按键互换
一.F1~F12恢复正常按键 联想Thinkpad的F1~F12键功能与其他笔记本是相反的! 也就是说,如果不按着Fn,按那几个功能键,实现的是属性设置的功能,比如直接按下F1键是静音,F2键是音量降 ...
- linux下如何查看某个软件 是否安装??? 安装路径在哪???
<1>.在linux下如何判断是否已经安装某个软件? 我的系统是red hat 我用命令rpm查是否安装了某个软件(例如: matlab 与 fluent ),得到了如下的结果: 我用rp ...
- Codeforces 938E Max History:排列 + 逆元【考虑单个元素的贡献】
题目链接:http://codeforces.com/problemset/problem/938/E 题意: 定义f(a): 初始时f(a) = 0, M = 1. 枚举i = 2 to n,如果a ...
- php get_magic_quotes_gpc()
magic_quotes_gpc函数在php中的作用是判断解析用户输入的数据,如包括有:post.get.cookie过来的数据增加转义字符“\”,以确保这些数据不会引起程序异常,特别是数据库语句因为 ...
- linux(centos)安装Nexus
1.解压nexus压缩包 tar xvzf ./nexus-2.13.0-01-bundle.tar.gz 2.修改配置文件: 修改jetty配置 [root@localhost nexus]# vi ...
- CSS基础(滑动门,雪碧图,网页布局)
3.11.2017 这一篇主要是关于滑动门技术的学习,还有雪碧图(sprite),也就是精灵图,还有一点昨天的css可见性的回顾,下面先来回顾下吧 CSS可见性(元素可见性) overflow: hi ...
- spring boot: 组合注解与元注解
package ch2.annotation; //target/elementType用来设定注解的使用范围 import java.lang.annotation.ElementType; imp ...
- php 微信接口API之长链接转短链接代码示例
<?php header("Content-Type: text/html; charset=utf-8"); $longurl; if(isset($_POST['long ...
- vue 全选与取消全选
所用知识点 1 v-model:监听input内容 2 watch:监听属性方法 参考https://cn.vuejs.org/v2/api/#watch 3 页面初始化调用函数 mounted 一: ...