分治与递归-循坏赛日程表

问题描述:设有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];} } }}

posted on 2017-01-22 10:15  qq77530202  阅读(145)  评论(0编辑  收藏  举报