一、循环赛日程表算法基本思想
循环赛日程表是基于分治的思想的。对于一个庞大的问题规模,我们无从下手,那么如果让你安排两个人的循环赛,你是不是可以很轻松的解决呢?那不废话吗,1选手和2选手干一场就是了!那么,如果是4个人呢,我们是否可以分成两组,1、2和3、4,分别给1、2安排比赛,3、4安排比赛。等他们内部战争解决了之后,再来挑衅外面的~。那么问题来了,挑衅外人,哪家强?问题貌似很复杂啊,但是你结合下面的图解应该很容易理解(第一行表示比赛的选手的编号,第二行表示第一天的比赛,例如第二行第一列表示:第一天1号选手和2号选手比赛。)
二、循环赛日程表的数据结构
二维数组记录日程表的比赛信息
三、循环赛日程表过程图解
四、算法源代码
/** 分治法,循环赛事日程表 */ #include <cstdio> #include <math.h> void Table(int k,int n,int **a); void input(int &k); void output(int **a,int n); int main() { int k; input(k); int n=1; //n=2k(k>=1)个选手参加比赛 for(int i=1; i<=k; i++) n *= 2; //根据n动态分配二维数组a int **a = new int *[n+1]; for(int i=0;i<=n;i++) { a[i] = new int[n+1]; } Table(k,n,a); printf("循环赛事日程表为:\n"); output(a,n); //释放空间 for(int i=0;i<=n;i++) { delete[] a[i]; } delete[] a; return 0; } void input(int &k) { printf("请输入k值:\n"); scanf("%d",&k); } void output(int **a,int n) { for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { printf("%d ",a[i][j]); } printf("\n"); } } void Table(int k,int n,int **a) { 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)*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; } }