單循環(huán)賽貝格爾編排法實現(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)民镜,按逆時針方向移動一個位置,就形成第二輪的編排表险毁。以此類推制圈,每一輪移動一個位置,生成剩余輪次的編排表畔况。最終形成的編排表如下:
<pre>
一 二 三 四 五 六 七
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
</pre>

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

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

<pre>
隊伍數(shù) 間隔數(shù)
<=4 0
5 - 6 1
7 - 8 2
9 -10 3
11-12 4
13-14 5
... ...
</pre>

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

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

<pre>
1 - 0
2 - 7
3 - 6
4 - 5
</pre>

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

Paste_Image.png

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

Paste_Image.png

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

Paste_Image.png

代碼實現(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。

<pre>
void BegerArrangement(int nAmount)
{
if (nAmount < 2 || nAmount > 90 )
return;

// 隊伍數(shù)量
int nFixAmount = nAmount;
// 最后一支隊伍的編號
int nLastPlayerNo = nAmount;
// 奇數(shù)隊伍弧呐,補上一支虛擬的隊伍闸迷,最后一支隊伍的編號為0
if (IsOdd(nAmount))
{
    ++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;
    else
        nFirstPlayerPos = (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];
            else
                nPlayer[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);
    else
        printf("%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");

}
</pre>

代碼地址:https://github.com/windpenguin/WindUtilities

參考
http://www.xxkt.cn/zhxk/2007/24920.html
http://baike.baidu.com/item/%E5%8D%95%E5%BE%AA%E7%8E%AF%E8%B5%9B%E5%88%B6?sefr=enterbtn
http://baike.baidu.com/item/%E8%B4%9D%E6%A0%BC%E5%B0%94%E7%BC%96%E6%8E%92%E6%B3%95?sefr=enterbtn

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市俘枫,隨后出現(xiàn)的幾起案子腥沽,更是在濱河造成了極大的恐慌,老刑警劉巖崩哩,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件巡球,死亡現(xiàn)場離奇詭異,居然都是意外死亡邓嘹,警方通過查閱死者的電腦和手機酣栈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來汹押,“玉大人矿筝,你說我怎么就攤上這事∨锛郑” “怎么了窖维?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵榆综,是天一觀的道長。 經(jīng)常有香客問我铸史,道長鼻疮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任琳轿,我火速辦了婚禮判沟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘崭篡。我一直安慰自己挪哄,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布琉闪。 她就那樣靜靜地躺著迹炼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪颠毙。 梳的紋絲不亂的頭發(fā)上斯入,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天,我揣著相機與錄音吟秩,去河邊找鬼咱扣。 笑死绽淘,一個胖子當(dāng)著我的面吹牛涵防,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播沪铭,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼壮池,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了杀怠?” 一聲冷哼從身側(cè)響起椰憋,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎赔退,沒想到半個月后橙依,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡硕旗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年窗骑,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漆枚。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡创译,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出墙基,到底是詐尸還是另有隱情软族,我是刑警寧澤刷喜,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站立砸,受9級特大地震影響掖疮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜颗祝,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一氮墨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧吐葵,春花似錦规揪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至凤藏,卻和暖如春奸忽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背揖庄。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工栗菜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蹄梢。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓疙筹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親禁炒。 傳聞我的和親對象是個殘疾皇子而咆,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內(nèi)容