單迴圈賽程安排問題

2021-09-08 09:46:49 字數 2417 閱讀 9163

首先,來解釋一下,什麼是單迴圈問題,其實,這是乙個我們在實現中經常遇到的問題。

問題描述:

賽程問題:有n個運動員進行單迴圈賽,即兩個運動員都要與其他所有運動員比賽一次。要求每個運動員每天只進行一次比賽,且整個賽程在n-1天內結束,運動員編號由1到n

注:n = 2^k

解題思想:

看到這個問題,我們的第一種想法當然就是用窮舉法,找出乙個可行的方案。其實這題並不適合用窮舉法去解決,因為其時間複雜度太大。下面來說說,如何使用分治的思想來解決這個問題。

按分治策略,我們可以將所有的選手分為兩半,則n個選手的比賽日程表可以通過n/2個選手的比賽日程表來決定。遞迴地用這種一分為二的策略對選手進行劃分,直到只剩下兩個選手時,就讓這兩個選手進行比賽就可以了。

日程表可用矩陣來標識,元素值為運動員編號,

列座標表示第幾天,下標從0開始,

並約定第0天,表示自己跟自己比賽,例如,對於只有兩個動員員的情況

1  2

2  1

表示,1的第1天跟2比賽,2的第一天跟1比賽。

下面來看看四個運動員的情況,如下:

1 2 3 4

2 1 4 3

3 4 1 2

4 3 2 1

可把它劃分為4個2*2的矩陣,即劃分為四組兩個動動員時的情況。

據此我們可以看到,將左上角小塊中的所有數字按其相對位置抄到右下角,又將左下角小塊中的所有數字按其相對位置抄到右上角,這樣我們就分別安排好了。

下面我們來看看如何用**(c/c++)實現它。

**實現:

#include using namespace std;

void gameschedule(int *table, int table_rank);

//單迴圈賽程演算法啟動函式

void gschedule(int *table, int table_rank,

int r1, int c1, int r2, int c2, int n);

//單迴圈賽程的安排實現

void inittable(int *table, int table_rank);

//初始化賽程表

void printtable(int *table, int table_rank);

//輸出賽程表

int main()

void gameschedule(int *table, int table_rank)

void gschedule(int *table, int table_rank,

int r1, int c1, int r2, int c2, int n)

int mr = (r2-r1)/2;

int mc = (c2-c1)/2;

n /= 2;//將運動員的人數減少一半

//為其左上角的四分之一的矩陣安排賽程

gschedule(table, table_rank, r1,c1, r1+mr,c1+mc, n);

//為其右上角的四分之一的矩陣安排賽程

gschedule(table, table_rank, r1, c1+mc+1, r1+mr, c2, n);

//為其左下角的四分之一的矩陣安排賽程

gschedule(table, table_rank, r1+mr+1, c1, r2, c1+mc, n);

//為其右下角的四分之一的矩陣安排賽程

gschedule(table, table_rank, r1+mr+1, c1+mc+1, r2, c2, n);

}}void inittable(int *table, int table_rank)

//設定第0天為與自己比賽

for(int i = 0; i < table_rank; ++i)

}void printtable(int *table, int table_rank)

{ //輸出賽程表

for(int i = 0; i < table_rank; ++i)

{for(int j = 0; j < table_rank; ++j)

cout << *(table+i*table_rank+j) <<' ';

cout《演算法分析:

我們可以通過使用乙個二維陣列來記錄矩陣,雖然這裡你看到的乙個一維的陣列,這是因為運動員的人數是通過輸入來確定的,所以必須使用動態記憶體分配,也就不能事先確定陣列的第二維(即列數)的大小,所以只好使用乙個一維陣列當二維陣列使用。然後使用變數table_rank來確定賽程表的階數(也可理解為一行有多少列,或運動員的人數)。表示式table+i*table_rank+j用於找出第i行第j列的元素的位址,所以

*(table+i*table_rank+j)就相當於平時大家熟悉的table[i][j]。

如果事先已經確定了人數,也可以不使用動態記憶體分配,而使用全域性變數來實現,則函式gschedule可少用前面的兩個引數。

單迴圈賽程安排問題

首先,來解釋一下,什麼是單迴圈問題,其實,這是乙個我們在實現中經常遇到的問題。問題描述 賽程問題 有n個運動員進行單迴圈賽,即兩個運動員都要與其他所有運動員比賽一次。要求每個運動員每天只進行一次比賽,且整個賽程在n 1天內結束,運動員編號由1到n 注 n 2 k 解題思想 看到這個問題,我們的第一種...

迴圈賽程安排

include stdio.h 為參加網球比賽的選手安排比賽日程,設有n 2k 位選手參加網球迴圈賽,迴圈賽共進行n 1天,每位選手要與其他n 1位選手都賽一場,且每位選手每天賽一場,不輪空。define maxlen 100 int b maxlen 2 記錄所有比賽場次對手 int j 0 比賽...

桌球單迴圈賽 桌球單迴圈比賽規則

桌球單迴圈比賽規則 一 桌球單迴圈比賽規則 迴圈賽是桌球競賽的一種基本比賽辦法。所謂迴圈賽就是使參加比賽的各力互相之間都直接比賽一次,又稱桌球單迴圈賽。讓我們一起看看桌球單迴圈比賽規則吧!桌球單迴圈賽比賽輪次的計算 如果參加的隊數是偶數,則比賽輪數為隊數減1。例如 8個隊參加比賽,比賽輪數為8 1 ...