首页 > 代码库 > 分治与递归-循坏赛日程表
分治与递归-循坏赛日程表
问题描述:设有n=2^k个运动员要进行网球循环赛。现要设计一个满足以下要求的比赛日程表:
(1)每个选手必须与其他n-1个选手各赛一次;
(2)每个选手一天只能参赛一次;
(3)循环赛在n-1天内结束。
请按此要求将比赛日程表设计成有n行和n列的一个表。表中一行的第一个数为选手编号,其他元素分别为第1天~第n-1天所遇到的选手。
思路: 先打印出大表的左上角,然后在补充其他角的信息。
分治策略:找规律发现,由于n个选手的比赛日程可以通过n/2个选手设计的比赛日程表决定。所以就可以缩小问题规模。但求法相同。
本题的分治是将 大表 分治为 大表的 左上角部分。然后利用左上角部分的信息补充其他角度表格
递归方法 :要求大表,就先求大表的左上角表。要求大表的左上角表,就要求大表的左上角表的左上角表,直到左上角表规模为1,此时
table[0][0]=1.然后就可以往回递归,先求出规模为4的表,再利用规模为4的表求出规模为16的表,直到递归结束。
void print(int table[100][100],int k) { if(k==0) { table[0][0]=1; } else { print(table,k-1); //作为已知条件来用,打印出了原问题左上角的表格 int n = 1,i,j; for(i=0;i<k;i++) { n = n * 2; } for(i=0;i<n/2;i++) { for(j=0;j<n/2;j++) { table[i+n/2][j] = table[i][j] + n/2;//补充右上角 table[i][j+n/2] = table[i][j] + n/2;//补充左下角 table[i+n/2][j+n/2] = table[i][j]; //补充右下角 } } } }
void print(int table[100][100],int k){if(k==0){table[0][0]=1;}else{print(table,k-1); //作为已知条件来用,打印出了原问题左上角的表格 int n = 1,i,j;for(i=0;i<k;i++) { n = n * 2; } for(i=0;i<n/2;i++){for(j=0;j<n/2;j++){table[i+n/2][j] = table[i][j] + n/2;table[i][j+n/2] = table[i][j] + n/2;table[i+n/2][j+n/2] = table[i][j];} } }}
分治与递归-循坏赛日程表