循環賽日程表問題


輸入正整數k表示有n=2^k個運動員進行循環比賽,需要設計比賽日程表。每個選手與其他n-1個選手各賽一次;每個選手一天只能賽一次;循環賽一共進行n-1天。

按此要求設計一張比賽日程表,該表有n行和n-1列,第i行第j列表示第i個選手第j天遇到的選手。

分析:

本題的方法有很多,遞歸是其中一種比較容易理解的方法。 如下圖所示是k=3時的一個可行解(第1列是選手編號),它是4塊拼起來的。 左上角是k=2時的一組解,左下角是左上角每個數加4得到,而右上角、 右下角分別由左下角、 左上角復制得到。

遞歸,每一次分為4個區域來處理。當然,也可以根據上面分析的規律直接模擬填充數組即可。循環k-1次,每一次填充除了左上角之外的另外3個區域。

代碼參考:

http://www.cnblogs.com/crx234/p/5988418.html

http://blog.csdn.net/liufeng_king/article/details/8488421

遞歸的划分過程可以參考殘缺棋盤的划分過程。

 

下面是循環填充的代碼

 1 #include <stdio.h>
 2 #define MAX 101
 3 //問題表示
 4 int k;             //求解結果表示
 5 int a[MAX][MAX]; //存放比賽日程表(行列下標為0的元素不用)
 6 void Plan(int k)
 7 {   int i,j,n,t,temp;
 8     n=2;            //n從2^1=2開始
 9     a[1][1]=1; a[1][2]=2; //求解2個選手比賽日程,得到左上角元素
10     a[2][1]=2; a[2][2]=1;
11     for (t=1;t<k;t++)      //迭代處理2^2(t=1)…,2^k(t=k-1)個選手
12     {
13         temp=n;             //temp=2^t
14         n=n*2;              //n=2^(t+1)
15         for(i=temp+1;i<=n;i++ )    //填左下角元素
16            for(j=1;j<=temp;j++)
17                a[i][j]=a[i-temp][j]+temp;
18         for(i=1;i<=temp;i++)//填右上角元素
19             for(j=temp+1;j<=n;j++)
20                 a[i][j]=a[i+temp][(j+temp)%n];
21         for(i=temp+1;i<=n;i++)//填右下角元素
22             for(j=temp+1;j<=n; j++)
23                 a[i][j]=a[i-temp][j-temp];
24     }
25 }
26 int main()
27 {
28     Plan(3);
29     for(int i=1;i<=3;i++)
30         {
31             for(int j=1;j<=3;j++)
32                 printf("%d ",a[i][j]);
33             printf("\n");
34         }
35     return 0;
36 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM