日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

单循环赛 贝格尔编排法实现

發(fā)布時間:2023/12/14 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 单循环赛 贝格尔编排法实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文鏈接
單循環(huán)賽,是指所有參賽隊伍都需跟其他隊伍比賽一次,根據(jù)比賽得分,勝負場次來排列名次。比賽隊伍為單數(shù)時,輪數(shù)等于隊伍數(shù),為雙數(shù)時,輪數(shù)等于隊伍數(shù)減一。如5支隊伍需比賽5輪,6支隊伍需比賽5輪。

首先介紹下逆時針輪轉(zhuǎn)法。將隊伍用阿拉伯?dāng)?shù)字從1開始編號,編排時將參賽隊伍平均分成左右兩排,左邊從1開始自上向下排,右邊按號數(shù)自下向上排,形成一個U型結(jié)構(gòu)。如果隊伍數(shù)為奇數(shù),則在最后加一個“0”,湊成偶數(shù)。與0比賽的隊伍該輪輪空。假設(shè)現(xiàn)在有7支隊伍參賽,加上一個0,湊成8支。根據(jù)前面所述排列好隊伍,然后將左右兩排分別平行連線,就形成第一輪比賽的編排表,即1-0,2-7,3-6,4-5,隊伍1在該輪輪空。第二輪開始,固定左上角的數(shù)字1,其余的數(shù)字想象成一個環(huán),按逆時針方向移動一個位置,就形成第二輪的編排表。以此類推,每一輪移動一個位置,生成剩余輪次的編排表。最終形成的編排表如下:

一 二 三 四 五 六 七

1—0 1—7 1—6 1—5 1—4 1—3 1—2

2—7 0—6 7—5 6—4 5—3 4—2 3—0

3—6 2—5 0—4 7—3 6—2 5—0 4—7

4—5 3—4 2—3 0—2 7—0 6—7 5—6

仔細觀察,會發(fā)現(xiàn)從第4輪開始,隊伍6總是跟上一輪輪空的隊伍比賽,這就是逆時針輪轉(zhuǎn)法的缺點,即第二輪的輪空隊從第四輪開始,每輪都與前一輪的輪空隊伍比賽。

貝格爾編排法與逆時針輪轉(zhuǎn)法類似,不過有兩個區(qū)別。一是交替固定最大的數(shù)字(或者0)在左上角和右上角,當(dāng)前輪次在左上角,則下一輪固定到右上角。二是固定最大數(shù)字(或者0)后,剩余的數(shù)字想象成一個環(huán),移動一定間隔,這個間隔根據(jù)隊伍數(shù)決定:

隊伍數(shù) 間隔數(shù)

<=4 0

5 - 6 1

7 - 8 2

9 -10 3

11-12 4

13-14 5

… …

假設(shè)有n(n>=4)支隊伍參賽,則間隔數(shù)的計算公式為(n+n%2-4)/2。

同樣以7支隊伍參賽為例,首輪還是

1 - 0

2 - 7

3 - 6

4 - 5

第二輪將0移到左上角,剩下的數(shù)字從1開始逆時針移動2個間隔,這里1將移到原來4所在的位置

第三輪將0移動到右上角,剩下的數(shù)字繼續(xù)逆時針移動2個間隔

剩下的輪次原理同上,最終編排表如下

代碼實現(xiàn)的思路如下,最大數(shù)字的位置只需根據(jù)前一輪的位置就能確定,其他數(shù)字都是按順序排列,形成一個有序的環(huán)。所以只需要確定1的位置,其他位置的數(shù)字都能確定。將位置按照第一輪的數(shù)字編號為1-8。在第一輪,1在位置1上。第二輪,1移動2個間隔,可以理解成移動3個位置,即1+3=4,取模一下,(1+3)%7=4,所以1將移到位置4。第三輪,繼續(xù)移動3個位置,(4+3)%7=0,這里0就是7,也就是1移到位置7。第四輪,(7+3)%7=3,1移到位置3。以此類推。要注意的是,要是1移到的位置跟0沖突,就移到相對位置。0在位置8,那么1就移到位置1,0在位置1,1就移到位置8。

運行效果

代碼實現(xiàn)

#include <iostream> using namespace std; void BegerArrangement(int nAmount) {if (nAmount < 2 || nAmount > 90)return;// 隊伍數(shù)量int nFixAmount = nAmount;// 最后一支隊伍的編號int nLastPlayerNo = nAmount;// 奇數(shù)隊伍,補上一支虛擬的隊伍,最后一支隊伍的編號為0if (nAmount % 2){++nFixAmount;nLastPlayerNo = 0;}// 輪數(shù)int nMaxRound = nFixAmount - 1;int nHalfAmount = nFixAmount / 2;// 移動的間隔int nStep = nFixAmount <= 4 ? 1 : (nFixAmount - 4) / 2 + 1;int nRound = 1;int nFirstPlayerPos = 1;int nLastPlayerPos = 1;int result[100][200] = {0};while (nRound <= nMaxRound){// 每次最后一個玩家的位置需要左右對調(diào)nLastPlayerPos = nFixAmount + 1 - nLastPlayerPos;if (nRound == 1)nFirstPlayerPos = 1;elsenFirstPlayerPos = (nFirstPlayerPos + nStep) % (nFixAmount - 1);if (nFirstPlayerPos == 0)nFirstPlayerPos = nFixAmount - 1;if (nFirstPlayerPos == nLastPlayerPos)nFirstPlayerPos = nFixAmount + 1 - nLastPlayerPos;for (int i = 1; i <= nHalfAmount; ++i){int nPos[2] = {i, nFixAmount - i + 1};int nPlayer[2] = {0, 0};for (int j = 0; j < 2; ++j){if (nPos[j] == nLastPlayerPos)nPlayer[j] = nLastPlayerNo;else if (nPos[j] < nFirstPlayerPos)nPlayer[j] = nFixAmount - nFirstPlayerPos + nPos[j];elsenPlayer[j] = nPos[j] - nFirstPlayerPos + 1;result[i - 1][(nRound - 1) * 2 + j] = nPlayer[j];}}++nRound;}for (int i = 1; i <= nMaxRound; ++i){if (i == 1)printf("%3s%-3d|", "r", i);elseprintf("%4s%-3d|", "r", i);}printf("\n");for (int i = 0; i < nHalfAmount; ++i){for (int j = 0; j < nMaxRound; ++j){printf("%-2d-%2d | ", result[i][j * 2], result[i][j * 2 + 1]);}printf("\n");}printf("\n\n"); } int main() {int n;cin >> n;BegerArrangement(n);return 0; }

代碼思路,編輯格式不易,大家覺得還可以可以點贊、收藏、關(guān)注一下吧!
也可以到我的個人博客參觀一下,https://motongxue.gitee.io

總結(jié)

以上是生活随笔為你收集整理的单循环赛 贝格尔编排法实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。