n位 正整數 比賽日程的安排

2021-09-26 21:48:17 字數 3381 閱讀 4374

設有n個運動員要進行網球迴圈比賽。設計乙個滿足要求比賽的演算法

(1)每個選手必須和其他n-1位選手進行比賽

(2)每個選手一天只能參加一場比賽(也可以不參加)

(3)當n為偶數時要進行n-1天的比賽;當n為奇數時要進行n天的比賽

#include

using namespace std;

int b[

100]

;//隨便設定的空間根據問題需要設定

int a[20]

[20];

void

copy1

(int n)}}

void

copyodd

(int n)

for(

int i =

1;i<=m;i++

)else

a[m+i]

[j]= a[i]

[j]+m;

//針對左下角進行處理

//if else 語句的設定主要是為了 a[i][j]+m 不超過n

}for

(int j=

2;j<=m;j++)}

}int

odd(

int n)

void

makecopy

(int n)

void

tournament

(int n)if(

odd(n)

)tournament

(n/2);

makecopy

(n);

}int

main()

}else

}return0;

}/*測試n=10

1 2 3 4 5 6 7 8 9 10

2 1 5 3 7 4 8 9 10 6

3 8 1 2 4 5 9 10 6 7

4 5 9 1 3 2 10 6 7 8

5 4 2 10 1 3 6 7 8 9

6 7 8 9 10 1 5 4 3 2

7 6 10 8 2 9 1 5 4 3

8 3 6 7 9 10 2 1 5 4

9 10 4 6 8 7 3 2 1 5

10 9 7 5 6 8 4 3 2 1

*/

注:當選手輪空時,將會顯示數字n+1

首先我們的想法肯定是分治法,但是奇數的情況下無法平等均分,

會存在輪空的情況,所以我們需要進行加一操作,加入n+1,實際代表的就是乙個輪空標記

首先我們要利用遞迴,遞迴的盡頭a[1][1] =1

在此基礎上我們想到遞迴到1過程中

我們會自然而然的想到所加入的機械人怎麼處理呢

我們需要根據n/2的奇偶性,來判斷一下是否是引入了機械人

這也就是makecopy的作用,然後我們再呼叫偶數演算法或者奇數演算法

偶數演算法就是copy1,即與計算機演算法設計與分析課本一致

奇數演算法就是copyodd

由此的框架函式基本

int odd(int n)

void makecopy(int n)

void copyodd(int n)

void copy1(int n)

void tournament(int n)

其中copyodd難以理解所以補充一下

按照我們正常的想法來想這個問題,我們最希望在原來的基礎上進行貼上

例如我們的6名隊員是如何在四名隊員的基礎上拓展的

因為tournament(3) 再分治時需要加乙個虛擬機械人所以是四位

copyodd(6)

四名隊員的日程安排

1 2 3 4

2 1 4 3

3 4 1 2

4 3 2 1

我們最希望是在不改動原有陣列的基礎上,進行日程的安排

所以對於左下角來說我們直接m+a[i][j]的方式進行填充

但是對於我們之前設定的四號機械人我們需要進行一下改動

所以每當a[i][j]>m時即是上一次機械人(也就是輪空的意思所以需要進行填充)

這個**簡單的表述實際是對輪空的處理,處理要改變的結果是一對隊員

a[i][j] = b[i]=m+i;

a[m+i][j] = (b[i]+m)%n=i;

按照這邏輯填充完的結果是:

1 2 3 4

2 1 5 3

3 6 1 2

4 5 6 1

5 4 2 6

6 3 4 5

剩餘的還有兩列沒有顯示,我們所要實現的不過是安排一組又一組的對手

這時候就體現了我們輔助陣列b的作用了

對於二維陣列我們需要兩次遍歷進行操作,然後j=2設定,是因為我們從m+j到2m

因為m+1列已經處理過了

我們需要通過這個輔助陣列來獲取右上角對手的編號,然後將當前i為右下角的值

b陣列的值是大於m的,其次通過改變i,j的值使得這兩列上下不會重複左右也不會重複

因為b[i+j-1]!=b[i]

i+j-1!=i&&i+j-1!=i+m

故可以獲得剩餘的對手,還不致使重複

for

(int i=

1;i<=m;i++

)}

至於設定b[m+i] = b[i]的原因是正好錯開

使得右上角的三行為

5 66 4

4 5實際類似於4 5 6的迴圈左移這樣可以使得安排妥當

補充右下角即可得到

1 2 3 4 5 6

2 1 5 3 6 4

3 6 1 2 4 5

4 5 6 1 3 2

5 4 2 6 1 3

6 3 4 5 2 1

貪婪演算法 去掉 n 位正整數中的 s 位

鍵盤輸入乙個高精度的正整數 n,去掉其中任意 s 個數字後剩下的數字按原左右次序將組成乙個新的正整數。程式設計對給定的n 和 s,尋找一種方案使得剩下的數字組成的新數最小。怎麼樣根據貪婪策略刪除數字呢?總目標是刪除高位較大的數字,具體的,相鄰兩位比較若高位比低位大,則刪除高位。c 如下 includ...

五位的正整數

建立乙個自定義列表 如何建立乙個註腳 注釋也是必不可少的 katex數學公式 新的甘特圖功能,豐富你的文章 uml 圖表 flowchart流程圖 匯出與匯入 給出乙個不多於五位的正整數,求 1 他是幾位數 2 分別輸出每位數字 3,按逆序輸出各位數字,如原數為12345,應輸出54321 你好!這...

正整數n的k拆分問題

演算法小菜鳥剛開始做poj,1664是乙個關於整數拆分的問題,即 將正整數n拆分成k個不能整數的和,0 k n,求有多少種差分方法。比如 將7差分成3個不同整數的拆分法有8中,其中1,1,5和1,5,1屬於同一種拆分法。該問題等同於 將n個完全相同的物品放到k個完全相同的容器中,求有多少種方法。由於...