算法思路:

  算法思路(N可能为奇数,也可能是偶数)总体思路:按分治策略,将所有分为两半,n个选手可以通过n/2个选手设计的比赛日程表来决定。递归地用一分为二的略对选手进行分割,直到只剩下两个选手。对于N为奇数的情况可以虚拟多一个选手,使其编程N+1个选手的日程表,最然后忽略虚拟运动员参与的比赛。对于分割时候N/2的情况也做特殊处理, 前n/2轮比赛空选手与下一个未参赛的选手进行比赛
存储结构:数组 a[i][j], a[i][j]表示运动员i在第j天所遇到的选手

详细思路:

详细思路:(1)分治法,Tourna(n):If n==1  a[1][1]=1;return;tourna(n/2);//递归分割copy(n); //填表(2)n为偶数的情况Copy()函数:A.将左上角递归计算出的小块的所有数字按其相对位置抄到右下角,B.将右上角的小块的所有数字加n/2后按其相对位置抄到左下角,将左下角的小块中的所有数字按其相对位置抄到右上角Viod copy(int n){Int m=n/2;For i=1àmFor j=1--->m{a[i][j+m]=a[i][j]+m;// 小块的数值抄到右下角a[i+m][j]=a[i][j+m];// 右上抄到左下a[i+m][j+m]=a[i][j];//   左下抄到右上}}----------------------------------------------------------------------------------------------------------------------(3)一般性描述:n为偶数; n是奇数时增加一个虚拟选手n+1,将问题转换为n是偶数的情形。tournament(n):if n==1 : a[1][1]=1;return;//分割到最后if n为奇数 :tournament(n+1);return;//奇数的情况加上虚拟选手tournament(n/2);//分割makecopy(n);//这个函数copy分n为偶数很n为奇数的情况(4) 判断奇偶odd(n):Return n&1;(5)makecopy()与copy相似,并区分奇偶情况makecopy(n):if n/2>1 &&add(n/2) copyodd(n);//对n/2为奇数的情况的处理else copy(n);//偶数的情况(6)copyodd(n)实现n/2为奇数的时候的复制n/2奇数的一种处理方法:前n/2轮比赛空选手与下一个未参赛的选手进行比赛Copyodd(n):Int m=n/2For i=1→mb[i]=m+i;b[m+i]=b[i];for i=1→mfor j=1→m+1{if a[i][j]>m:a[i][j]=b[i];a[m+i][j]=(b[i]+m)%n;elsea[m+i][j]=a[i][j]+m;for j=2→ma[i][m+j]=b[i+j-1];a[b[i+j-1]][m+j]=i}三、时间效率:T(n)=T(n/2)+f(n)f(n)为copy的时间f(n)=(n/2)^2推出:T(n)=T(n/2)+(n/2)^2N规模的问题做logN次f(n)T(n)属于O(∑O((n/(2^k))^2)) 1<=k<log(n) 也就是T(n)∈O(n^2)

如有不懂参考这位博主的详解:
点击进入
C++代码实现如下:

#include<bits/stdc++.h>
using namespace std;
const int size = 50;
//数组 a[i][j], a[i][j]表示运动员i在第j天所遇到的选手
int a[size][size];
//运动员个数
int n;
//判断奇偶
int odd(int n)//奇数时返回1
{if(n%2==1)return 1;else return 0;
}
//打印结果
void print()
{if(odd(n))   // n为奇数和偶数输出情况不同,要分别考虑{for(int i = 1; i<=n; i++){for(int j = 1; j<=n+1; j++)if(a[i][j] == n+1)cout << "0  ";elsecout << a[i][j] << "  " ;cout << endl;}}else{for(int i = 1; i<=n; i++){for(int j = 1; j<=n; j++)cout << a[i][j] << "  " ;cout << endl;}}
}
// 实现n/2为奇数时的复制
void copyodd(int n)
{int b[size];int m = n/2;/*因为2m+1已经超出n的范围,所以我们将值为m+1和2m+1的队组成一组,即1—m+1,2—m+2,3—m+3,……,m—n.
因为它们之间都相差m,所以可以用一个数组b的索引和值的对应关系来表示: */for(int i = 1; i<=m; i++){b[i] = m+i;b[m+i] = b[i];}/*1--m行+m得到m+1--n行的值*/for(int i = 1; i<=m; i++){for(int j=1; j<=m+1; j++){if(a[i][j] > m){a[i][j] = b[i];a[m+i][j] = (b[i] + m)%n;}elsea[m+i][j] = a[i][j] + m;}for(int j = 2; j<=m; j++){//在m+1到n之间循环取值,且每次取m-1个 a[i][m+j] = b[i+j-1];a[b[i+j-1]][m+j] = i;//剩下未分配的随之解决}}
}
//n为偶数的情况copy()函数
void copy(int n)
{int m = n/2;for(int i = 1; i<=m; i++)for(int j = 1; j<=m; j++){a[i][j+m] = a[i][j] + m;//相应位置加2放到右上角 a[i+m][j] = a[i][j+m];//右上抄到左下 a[i+m][j+m] = a[i][j];//左上复制到右下 }
}
//makecopy 与copy算法类似,但是要区分n/2为奇数或偶数的情形
void makecopy(int n)
{if(n/2 > 1 && odd(n/2))copyodd(n);//对n/2为奇数时处理 elsecopy(n);//偶数时处理
}
//分治法
void tournament(int n)
{if(n == 1){a[1][1] = 1;return;}if(odd(n)){tournament(n+1);return;}tournament(n/2);makecopy(n);
}
int main()
{int i,j;cin >> n;tournament(n);print();
}

结果:

算法:循环赛日程表_一般化(n可以为奇数,也可以为偶数)相关推荐

  1. 用递归与分治策略求解网球循环赛日程表_算法设计:分治法(比赛日程安排)...

    一.算法思路 1.思路 分治算法的思想是:对于一个规模位N的问题,若该问题可以容易解决(比如规模N较小),则直接解决,否则将其分解为M个规模较小的子问题,这些子问题互相独立,并且与原问题形式相同,递归 ...

  2. 分治算法 —— 循环赛日程表

    1. 问题描述: 设有n=2^k个运动员要进行网球循环赛.现要设计一个满足以下要求的比赛日程表: (1)每个选手必须与其他n-1个选手各赛一次: (2)每个选手一天只能参赛一次: (3)循环赛在n-1 ...

  3. 用递归与分治策略求解网球循环赛日程表_分治、动态规划、回溯、贪心一锅炖

    「观感度:五颗星」 「口味:东北一锅出」 「烹饪时间:10min」 本文已收录在 Github github.com/Geekhyt,感谢Star. 数据结构与算法系列专栏第四弹来袭,往期专栏链接如下 ...

  4. python实现循环赛日程表问题的算法_循环赛日程表的分治算法实现实验报告gxl.doc...

    循环赛日程表的分治算法实现实验报告gxl PAGE PAGE 2 深 圳 大 学 实 验 报 告 课程名称: 算法设计与分析 实验项目名称: 分治算法 --矩阵相乘的Strassen算法及时间复杂性分 ...

  5. python实现循环赛日程表问题的算法_循环赛日程表的分治算法实现实验报告_gxl.doc...

    循环赛日程表的分治算法实现实验报告_gxl 深 圳 大 学 实 验 报 告 课程名称: 算法设计与分析 实验项目名称: 分治算法 --矩阵相乘的Strassen算法及时间复杂性分析 或--循环赛日程表 ...

  6. 循环赛日程表非递归Java_王晓东《算法设计与分析》课件.ppt

    <王晓东<算法设计与分析>课件.ppt>由会员分享,可在线阅读,更多相关<王晓东<算法设计与分析>课件.ppt(356页珍藏版)>请在人人文库网上搜索. ...

  7. 循环赛日程表算法——分治法

    一.问题描述: 设有n=2^{k}个选手要进行网球循环赛,要求设计一个满足以下要求的比赛日程表: (1)个选手必须与其他n-1个选手各赛一次: (2)每个选手一天只能赛一次. 按此要求,可将比赛日程表 ...

  8. 递归与分治策略算法之循环赛日程表

    递归与分治策略算法之循环赛日程表 1.先简单的来介绍一下分治策略的思想 分治策略的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,分解出来的子问题与原问题相同,并且相互独立.通过递归去解决子 ...

  9. 循环赛日程表问题(分治算法)

    循环赛日程表问题(分治算法) 设有n=2kn=2^kn=2k个运动员要进行网球循环赛.现要设计一个满足以下要求的比赛日程表: (1)每个选手必须与其他n−1n-1n−1个选手各赛一次: (2)每个选手 ...

最新文章

  1. 必看,61篇NeurIPS深度强化学习论文解读都这里了
  2. MonkeyRunner 的使用一
  3. python一直报缩进错误_如何避免Python中的缩进错误
  4. [bzoj4590][Shoi2015]自动刷题机
  5. VB中判断空的几种方法,Null, Missing, Empty, Nothing, vbNullString区别
  6. 这份程序员的简历刷爆了九月的朋友圈
  7. linux基础知识必掌握知识[自己原来上学总结的难免有错误,多谢指点]
  8. Mac下提示APP已损坏,打不开,请移至废纸篓
  9. php strtoupper 和 array_change_key_case 字符串转大写,小写
  10. tomcat使用ssl_使用SSL和Spring Security保护Tomcat应用程序的安全
  11. loj2245 [NOI2014]魔法森林 LCT
  12. Tcp三次握手和四次挥手状态图
  13. 服务器好玩的项目_GitHub 上有什么好玩的项目?(附地址)
  14. python汇总数据的程序_Python数据处理常用程序模块汇总
  15. 互联网世界的“人工智能”——探秘“深度学习”的前世今生
  16. VC实现文件拖拽获取文件名
  17. 谭浩强C语言(第三版)习题9.10
  18. 类型转化异常 Java Object转 int
  19. 英语知识系列:26个字母在单词中的发音总结
  20. 《如何正确评估自己的工作能力》--马薇薇

热门文章

  1. 图片来自微信公众平台未经许可不可引用|解决经验分享
  2. 兔子繁殖问题与解决方案
  3. .war直接运行的方法
  4. 判断组合数奇偶性(组合数学)
  5. LVM精简卷(Thinly-Provisioned Logical Volumes)
  6. 草图大师怎么取消组件关联_草图大师隐藏其他组件快捷键是什么?
  7. 关于String在OC中的一些操作(长沙戴维营)
  8. Java实现——判断一个数是否是质数
  9. 电脑创建QQ联系人快捷方式方法:
  10. 南方地区也有暖气市场,暖气片成为销量增长主力