循环赛日程表(用来说明算法导论上的题目!!)

设有n=2k个选手参加比赛,要求设计一个满足一下要求的比赛日程表:

(1)每个选手必须与其他的n-1个选手个比赛一次;

(2)每个选手每天只能赛一次 。

按此要求可以把比赛日程表设计成一个n行n-1列的二维表,其中第i行第j列表示第i个选手在 第j天比赛的选手。

代码:(分治策略)

 1 #include<stdio.h>
 2 #include<math.h>
 3
 4 void gametable(int k)
 5 {
 6     int a[100][100];
 7     int n,temp,i,j,p,t;
 8     n=2;//k=0两个参赛选手日程可以直接求得
 9     a[1][1]=1;a[1][2]=2;
10     a[2][1]=2;a[2][2]=1;
11     for(t=1;t<k;t++)//迭代处理,依次处理2^n....2^k个选手的比赛日程
12     {
13         temp=n;n=n*2;//填左下角元素
14         for(i=temp+1;i<=n;i++)
15             for(j=1;j<=temp;j++)
16                 a[i][j]=a[i-temp][j]+temp;//左下角和左上角元素的对应关系
17         for(i=1;i<=temp;i++)//将左下角元素抄到右上角
18             for(j=temp+1;j<=n;j++)
19                 a[i][j]=a[i+temp][(j+temp)%n];
20         for(i=temp+1;i<=n;i++)//将左上角元素抄到右下角
21             for(j=temp+1;j<=n;j++)
22                 a[i][j]=a[i-temp][j-temp];
23
24     }
25     printf("参赛人数为:%d\n(第i行第j列表示和第i个选手在第j天比赛的选手序号)\n",n);
26     for(i=1;i<=n;i++)
27         for(j=1;j<=n;j++)
28         {
29             printf("%d ",a[i][j]);
30                 if(j==n)
31                 printf("\n");
32
33         }
34 }
35
36 int main()
37 {
38     int k;
39     printf("比赛选手个数为n(n=2^k),请输入参数K(K>0):\n");
40     scanf("%d",&k);
41     if(k!=0)
42     gametable(k);
43
44 }
时间: 2024-12-21 06:29:27

循环赛日程表(用来说明算法导论上的题目!!)的相关文章

算法导论8:数据结构——栈 2016.1.8

栈在暑假的时候接触过了,当时还写了个计算器,用的中缀表达式后缀表达式的栈操作. http://www.cnblogs.com/itlqs/p/4749998.html 今天按照算法导论上的讲解规范了一下代码.主要是栈的初始化.判断空栈.入栈.出栈.遍历栈. #include<stdio.h> #define MAXTOP 10 struct _stack { int top; int num[MAXTOP+1]; }s; void init(struct _stack &S) { S.

算法导论学习---红黑树具体解释之插入(C语言实现)

前面我们学习二叉搜索树的时候发如今一些情况下其高度不是非常均匀,甚至有时候会退化成一条长链,所以我们引用一些"平衡"的二叉搜索树.红黑树就是一种"平衡"的二叉搜索树,它通过在每一个结点附加颜色位和路径上的一些约束条件能够保证在最坏的情况下基本动态集合操作的时间复杂度为O(nlgn).以下会总结红黑树的性质,然后分析红黑树的插入操作,并给出一份完整代码. 先给出红黑树的结点定义: #define RED 1 #define BLACK 0 ///红黑树结点定义,与普通

[算法导论 Ch9 中位数和顺序统计量] Selection in O(n)

1. 寻找第k大(小)的数 假设数据存储在数组a[1..n]中 首先,寻找一个数组中最大或者最小的数,因为最大(小)的数一定要比其他所有的数大(小),因此至少要比较完所有的pair才能确定,所以时间复杂度在O(n).那么寻找第k大(小)呢? 比较直观的,就是对数组中国所有的数据先进行排序,在我们这种渣渣的计算机入门选手而言,可选的有QuickSort,MergeSort和HeapSort,甚至是ShellSort等一些比较高级的方法啊...一般的代价都在O(n*logn)上,然后直接取出即可.

算法导论2:几个习题 2016.1.2

一.在归并排序中对小数组采用插入排序(放在上一篇里了): 二.冒泡排序 冒泡排序效率几乎是所有排序里最低的,但却很流行,就是因为它的变成复杂度也是最低的.大多数时候,效率还不及插入排序,其实冒泡排序.插入排序.选择排序基本上效果是差不多的(这个效果不是功能..功能上讲肯定差不多啊都是排序),只是过程略有区别.既然写到这里,就自己总结一下三者吧. 1.插入排序——摸扑克牌的过程 假定前一个是有序的,把第二个插进它应当在的位置,那么前两个就是有序的了,把第三个插进它应当在的位置,那么前三个就是有序的

算法导论第九章中位数和顺序统计量(选择问题)

本章如果要归结成一个问题的话,可以归结为选择问题,比如要从一堆数中选择最大的数,或最小的数,或第几小/大的数等, 这样的问题看似很简单,似乎没有什么可研究的必要,因为我们已经知道了排序算法,运用排序+索引的方式不就轻松搞定了?但细想,排序所带来的时间复杂度是不是让这个问题无形之中变得糟糕.那算法研究不就是要尽可能避免一个问题高复杂度地解决,让那些不敢肯定有无最优解的问题变得不再怀疑,这也是算法研究者所追求的一种极致哲学.既然排序让这个问题解决的性能无法确定,那我们就抛开排序,独立研究问题本身,看

算法导论第七章快速排序

一.快速排序概述 关于快速排序,我之前写过两篇文章,一篇是写VC库中的快排函数,另一篇是写了快排的三种实现方法.现在再一次看算法导论,发现对快速排序又有了些新的认识,总结如下: (1).快速排序最坏情况下的时间复杂度为O(n^2),虽然最坏情况下性能较差,但快排在实际应用中是最佳选择.原因在于:其平均性能较好,为O(nlgn),且O(nlgn)记号中的常数因子较小,而且是稳定排序. (2).快速排序的思想和合并排序一样,即分治.快排排序的分治思想体现在: a.首先从待排序的数中选择一个作为基数,

字符串匹配算法的C语言实现-算法导论第三版(1)

因为最近准备开始学习做一些小的Android项目练手,看上了系统级的三个应用,拨号盘,通讯录和短信,准备从最简单的拨号做起,但是因为这些应用中都不可避免的会有自动提示,我觉得设计到的就是字符串匹配问题,这里准备使用C语言来实现,将来通过JNI集成到应用当中. 1.首先是朴素匹配,实际上就是穷举: 用C语言实现的函数我放到这里: 1 void naive_string_match(char *t,char *p){ 2 int n = strlen(t); 3 int m = strlen(p);

算法导论学习之快排+各种排序算法时间复杂度总结

快排是一种最常用的排序算法,因为其平均的时间复杂度是nlgn,并且其中的常数因子比较小. 一.快速排序 快排和合并排序一样都是基于分治的排序算法;快排的分治如下: 分解:对区间A[p,r]进行分解,返回q,使得A[p–q-1]都不大于A[q] A[q+1,r]都大于A[q]; 求解:对上面得到的区间继续递归进行快排 合并:因为快排是原地排序,所以不需要特别的合并 从上可以看出最重要的就是分解函数,其按关键值将数组划分成3部分,其具体实现的过程见代码注释. 我们一般取数组的最后一个元素作为划分比较

算法导论学习笔记(2)-归并排序

今天学习了算法导论上的归并排序算法,并且完成了在纸上写出伪代码,以前就学过归并但是理解的不够透彻,以 前还一直困惑:为什么明明归并排序比快排的时间复杂度更稳定,为什么库函数不用归并而用快排,现在知道原因了,因为归并排序必须开额外的空间,而且空间开销还比较大,下面介绍算法: 首先,归并排序用到了分治的思想,把大数据分成若干个小数据,然后再分别对小数据进行处理,最后把小数据 合并成大数据. 其次,归并排序用到了一个最重要的特点,就是把两组已经排序的数据合并成一组有序数据,并且该过程的时间复 杂度为O