設有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個完全相同的容器中,求有多少種方法。由於...