分治法——循环赛日程表
来源:互联网 发布:java性能优化 编辑:程序博客网 时间:2024/04/29 15:12
问题描述
设有n=2k个运动员要进行羽毛球循环赛,现要设计一个满足以下要求的比赛日程表:
(1)每个选手必须与其它n-1个选手各赛一次;
(2)每个选手一天只能比赛一次;
(3)循环赛一共需要进行n-1天。
由于n=2^k,显然n为偶数。 按分治策略,将所有的选手分为两半,n个选手的比赛日程表就可以通过为n/2个选手设计的比赛日程表来决定。递归地用对选手进行分割,直到只剩下2个选手时,比赛日程表的制定就变得很简单。这时只要让这2个选手进行比赛就可以了。
分治法求解思路
(1)如何分,即如何合理地进行问题的分解?
一分为二
(2)如何治,即如何进行问题的求解?
进行合并
(3)问题的关键——发现循环赛日程表制定过程中存在的规律性。
循环赛日程表算法描述:
Void Round_Robin_Calendar(int k, int **a){ int n=1,i,j,s; n = 1<<k; for(i=1;i<=n;i++) a[1][i]=i; int m=1; for(s=1;s<=k;s++) //问题划分的次数 { n/=2; for(int t=1;t<=n;t++) //每一部分的问题进行单元格的填充 for(i=m+1;i<=2*m;i++) //控制行 for(j=m+1;j<=2*m;j++) //控制列 { a[i][j+(t-1)*m*2]=a[i-m][j+(t-1)*m*2-m]; a[i][j+(t-1)*m*2-m]=a[i-m][j+(t-1)*m*2]; } m*=2; }}
代码实现
#include <iostream>using namespace std;void Round_Robin_Calendar(int **a,int k);int main(){ int n,k; cin>>k; n = 1<<k; int **a = new int *[n]; for(int i = 1 ; i <= n ; i++) a[i] = new int[n]; Round_Robin_Calendar(a, k); for(int i = 1 ; i<= n ; i++) { for(int j = 1 ; j <= n ; j++) cout<<a[i][j]<<" "; cout<<endl; } return 0;}void Round_Robin_Calendar(int **a,int k){ int n; n = 1<<k; for(int i = 1 ; i <= n ; i++) a[1][i] = i; int m = 1; for(int s = 1 ; s <= k ; s++) { n /= 2; for(int t = 1 ; t <= n ; t++) for(int i = m+1 ; i <= 2*m ; i++) for(int j = m+1 ; j <= 2*m ; j++) { a[i][j+(t-1)*2*m] = a[i-m][j+(t-1)*2*m-m]; a[i][j+(t-1)*2*m-m] = a[i-m][j+(t-1)*2*m]; } m *= 2; }}
测试
阅读全文
0 0
- 分治法——循环赛日程表
- 分治法——循环赛日程表
- 分治——循环赛日程表
- 循环赛日程表-分治法
- 分治法,循环赛日程表
- 循环赛日程表《分治法》
- 循环赛日程表--分治法
- 循环赛日程表 分治法
- 分治与递归——循环赛日程表
- 分治法:循环赛日程表问题
- [算法之分治法应用] 循环赛日程表
- 分治法--循环赛日程表
- 用分治法解决循环赛日程表
- 分治算法--循环赛日程表
- 循环赛日程表(分治)
- 循环赛日程表(分治)
- 分治中循环赛日程表
- 循环赛日程表(分治)
- 第1章:Java语言概述(day01)
- 消息队列技术介绍
- 用U盘重装了Windows 7, 用起来很爽
- python里使用正则表达式的内嵌功能选项标志
- 服务计算——agenda
- 分治法——循环赛日程表
- 2017.11.3作业
- Java字符串操作
- 线段树入门
- cocos2dx 持续学习(三) 场景切换、弹出对话框
- TCP/IP 详解:arp 学习笔记
- 习题5.5 5.6
- Python的Cookie详解
- Python 如何用列表实现栈和队列