迴圈賽日程安排問題
阿新 • • 發佈:2018-11-03
設有n=2k個選手要進行網球迴圈賽,要求設計一個滿足以下要求的比賽日程表:
(1)每個選手必須與其他n-1個選手各賽一次;
(2)每個選手一天只能賽一次。
按此要求,可將比賽日程表設計成一個 n 行n-1列的二維表,其中,第 i 行第 j 列表示和第 i 個選手在第 j 天比賽的選手。
按照分治的策略,可將所有參賽的選手分為兩部分,n=2k個選手的比賽日程表就可以通過為n/2=2k-1個選手設計的比賽日程表來決定。遞迴地執行這種分割,直到只剩下2個選手時,比賽日程表的制定就變得很簡單:只要讓這2個選手進行比賽就可以了。
#include <stdio.h> using namespace std; #define MAX 100 int a[MAX][MAX]; void GameTable(int k) { int n = 2; a[1][1] = 1; a[1][2] = 2; a[2][1] = 2; a[2][2] = 1; for (int t = 1; t < k; t++) { int temp = n; n = n*2; //填左下角元素 for (int i = temp+1; i <= n; i++) { for (int j = 0; j <= temp; j++) { a[i][j] = a[i-temp][j] + temp; } } //填右上角元素 for (int i = 1; i <= temp; i++) { for (int j = temp+1; j <= n; j++) { a[i][j] = a[i+temp][(j+temp)%n]; } } //填右下角元素 for (int i = temp+1; i <= n; i++) { for (int j = temp+1; j <= n; j++) { a[i][j] = a[i-temp][j-temp]; } } } } int main() { int k = 4; GameTable(k); for (int i = 1; i <= 6; i++) { for (int j = 1; j <= 6; j++) { printf("%i",a[i][j]); printf(" "); } printf("\n"); } }