1. 程式人生 > >演算法-分治法例項:迴圈賽日程安排問題

演算法-分治法例項:迴圈賽日程安排問題

一、問題描述

  1. 設有 n(2^k)位選手參加網球迴圈賽,迴圈賽一共需要進行 n-1天,每位選手需要和其他的 n-1 位選手各比賽一場,不輪空。試著安排這個比賽的安排日程。

二、問題分析

本問題可以利用分治法來進行求解,設 n位選手被順序標號為1,2,3,……,n。比賽的日程是一個n 行和 n - 1 列的表,第 i 行第j 列就是第i 號選手的第 j 天的比賽對手。
想要用分治法來設計日程表,就是從其中一半的選手的比賽日程來匯出所有選手的比賽日程,從眾所周知的只有兩個選手的比賽日程出發,反覆推理和擴充整個比賽日程,直到第 n 位選手的比賽日程安排好了為止。
接下來是程式:


#include <stdio.h>
#include <math.h> #include <malloc/malloc.h> //採用分治法來進行網球迴圈賽的基本賽制的安排。 int ** GameTable(int k){ //首先分配一個矩陣 A 用來存放將要相互比賽的結果,第一列為所有選手的編號,每一行就是該選手和其他選手的比賽次序,且不使用下標為0的元素。 int ** A = (int**)malloc(sizeof(int*)*((int)pow(2, k))+1); int i,j,t; for (i = 1;i <= (int)pow(2, k);i++) { A[i] = (int
*)malloc(sizeof(int)*((int)pow(2, k)+1)); } //初始化基本元素並開始利用分治法來對時程表進行擴充 int n = 2;//遞增用於擴充安排表的變數 A[1][1] = 1; A[1][2] = 2; A[2][1] = 2; A[2][2] = 1; for (t = 1; t < k; t++) { //用分治法來填充日程表 int temp = n; n *= 2; //擴充左下角 for (i = temp + 1; i <= n; i++) { for
(j = 1; j <= temp; j++) { A[i][j] = A[i-temp][j] + temp; } } //擴充右上角 for (i = 1; i <= temp; i++) { for (j = temp + 1; j <= n; j++) { A[i][j] = A[i][j-temp] + temp; } } //擴充套件右下角 for (i = temp + 1; i <= n; i++) { for (j = temp + 1; j <= n; j++) { A[i][j] = A[i-temp][j-temp]; } } } return A; } //初始化輸入並且列印輸出結果 void InputAndOut(){ int CounterOfPeopleInTennis = 0; printf("請輸入這一屆參加比賽的選手人數有(必須為二的冪不然無法安排比賽):"); scanf("%d",&CounterOfPeopleInTennis); if (CounterOfPeopleInTennis % 2 != 0) { printf("輸入錯誤!請準備重新輸入:\n"); InputAndOut(); } else{ int k = 0; while (CounterOfPeopleInTennis != 1) { k++; CounterOfPeopleInTennis /= 2; } int ** Tennis_People; Tennis_People = GameTable(k); printf("本次迴圈網球賽的對決安排結果如下:\n"); for (int i = 1; i <= (int)pow(2, k); i++) { for (int j = 1; j <= (int)pow(2, k); j++) { printf("%3d",Tennis_People[i][j]); } printf("\n"); } } } int main(int argc, const char * argv[]) { InputAndOut(); return 0; }

相關推薦

演算法-治法例項迴圈賽日程安排問題

一、問題描述 設有 n(2^k)位選手參加網球迴圈賽,迴圈賽一共需要進行 n-1天,每位選手需要和其他的 n-1 位選手各比賽一場,不輪空。試著安排這個比賽的安排日程。 二、問題分析 本問題可以利用分治法來進行求解,設 n位選手被順序標號為1,2,

演算法05二分搜尋演算法——治法Part1

摘自網路: 分治法的設計思想是,將一個難以直接解決的大問題,分割成一些規模較小的相同問題,以便各個擊破,分而治之。 分治法所能解決的問題一般具有以下幾個特徵: 1.該問題的規模縮小因為問題的計算複雜性一般是隨著問題規模的增加 2.該問題可以分解為若干個規模較小的相同問題,即

迴圈賽日程安排問題

設有n=2k個選手要進行網球迴圈賽,要求設計一個滿足以下要求的比賽日程表: (1)每個選手必須與其他n-1個選手各賽一次; (2)每個選手一天只能賽一次。         按此要求,可將比賽日程表設計成一個 n 行n-1列的二維表,其中,第 i 行

求兩個等長有序陣列的中位數的logN演算法 治法

http://blog.csdn.net/yangliuy/article/details/7194199 題目:有兩個長為n的非遞減陣列A和B,把B接在A的後面變成長為2n的陣列C。設計演算法求C的中位數(第n小數)。 思路:O(n)的演算法很容易找到,關鍵是用二

最近點對演算法治法實現

內容會持續更新,有錯誤的地方歡迎指正,謝謝! 前言:博主最近正在學習《演算法》這門專業課程,這是該課程的第二次上機題目,我把自己的解題方法分享給大家,歡迎討論! 題目: 建立100個隨機點,並計算最近的兩個點之間的距離,輸出隨機生成的100個點的座標、最

五大常用演算法——治法,動態規劃,回溯法,分支界限法,貪心演算法

分治演算法 一、基本概念    在電腦科學中,分治法是一種很重要的演算法。字面上的解釋是“分而治之”,就是把一個複雜的問題分成兩個或更多的相同或相似的子問題,再把子問題分成更小的子問題……直到最後子問題可以簡單的直接求解,原問題的解即子問題的解的合併。這個技巧是很多高效

演算法導論 第二章演算法入門 筆記 (插入排序、迴圈不變式、演算法分析、最好和最壞時間複雜度、選擇排序、治法、合併排序)

插入排序: 排序問題的定義如下: 輸入:N個數{a1, a2,..., an }。 輸出:輸入序列的一個排列{a'1 ,a'1 ,...,a'n },使得a'n <=a' n<=...<

六中常用演算法設計窮舉法、治法、動態規劃、貪心法、回溯法和分支限界法

演算法設計之六種常用演算法設計方法 1.直接遍歷態(窮舉法)        程式執行狀態是可以遍歷的,遍歷演算法執行每一個狀態,最終會找到一個最優的可行解;適用於解決極小規模或者複雜度線性增長,而線

演算法優化最大欄位和,雙指標遍歷(n^2),治法(nlogn),動態規劃(n)

最大欄位和,有點類似與最長公共子序列,這裡是求連續一段求和最大的一段,比如[-2,11,-4,-4,13,-5,-2]最大求和的連續一段為11,-4,-4,13,和為16. 最基本的雙針模型遍歷,兩個指標,分別代表最大和序列的起始和終止,演算法時間複雜度O(n^2) # 以下演算法時

治法BFPTR演算法找第k小

BFPTR演算法 來自於Blum、Floyd、Pratt、Rivest、Tarjan這5個人,一起釋出了一篇名為 “Time bounds for selection” 的論文,有興趣可以看一下:https://pan.baidu.com/s/1QEWjZBrjEJ7zTIrI99sFY

治法關於選擇演算法,找最大,找最小,同時找最大和最小,找第二大

找最大或者最小,蠻力演算法為最優的演算法,需要比較n-1次 # 這個已經是最優的演算法了,比較n-1次 def findMax(arr): max_pivot = arr[0] for i in range(1,len(arr)): if arr

js演算法治法-歸併排序

歸併排序(合併排序)是一個遞迴演算法,這個演算法的理解其實可以藉助下面這個圖: 對於原始的陣列2,1,3,8,5,7,6,4,10,在整個過程執行的是順序是途中紅色編號1-20。雖然我們描述中說的是程式先分解,再歸併,但實際過程是一邊分解一邊歸併,前半部分分先排好序,後半

0x05演算法設計與分析複習(二)演算法設計策略-治法2

參考書籍:演算法設計與分析——C++語言描述(第二版) 演算法設計策略-分治法 二分搜尋 問題描述 在有序表(已按關鍵字值非減排序)中搜索給定元素的問題。 分治法求解 設有一個長度為n的有序表(a0,a1,⋯,an−1),要求

演算法07棋盤覆蓋——治法Part3

(3)棋盤覆蓋 在一個2k×2k 個方格組成的棋盤中,恰有一個方格與其它方格不同,稱該方格為一特殊方格,且稱該棋盤為一特殊棋盤。在棋盤覆蓋問題中,要用圖示的4種不同形態的L型骨牌覆蓋給定的特殊棋盤上除特殊方格以外的所有方格,且任何2個L型骨牌不得重疊覆蓋。 分治法的思想

演算法治法之二分查詢

一、分治法(三步) 分解:待解決的問題 分成 若干個子問題,子問題的求解方式跟之前的問題一樣 治理:各個子問題求解 合併:子問題的解合併 二、二分查詢 1.前提條件           有序的集合或者陣列 2.演算法思想       a.定位中間的元素

分治演算法乒乓球比賽的日程安排

乒乓球比賽的日程安排 問題: 設有n位選手參賽,初賽進行n-1天,每位選手每天必須比賽一次,不能輪空。程式設計求解賽程安排。 分析: 1、求n位選手的賽程安排,可採用分治演算法的思想,將問題規模不斷縮

js演算法治法-歸併排序之合併有序陣列

     合併有序陣列是合併排序重要的一步,下面js演示了每一步的操作過程  附程式碼: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEA

演算法設計與分析——治法

前言 本文重點回顧了卜老師課堂上關於分治演算法的一些常見的問題。加油吧!ヾ(◍°∇°◍)ノ゙ 分治法(Divide and Conquer) 當面對一個問題的時候,我們可能一下子找不到解決問題的方法。此時,我們可以考慮將問題規模最小化,先看看當問題規模變小以後,我們如何去解決

例項建立一個表格,頁顯示資料(MongoDB資料庫儲存),功能實現增刪改查

需求:建立一個表格,分頁顯示資料,功能:實現增刪改查 效果圖: 自動建立一個專案 命令列: express mongodb-demo --view=ejs cd mongodb-demo npm install npm install mongodb --save npm sta

一個隱馬爾科夫模型的應用例項中文

什麼問題用HMM解決 現實生活中有這樣一類隨機現象,在已知現在情況的條件下,未來時刻的情況只與現在有關,而與遙遠的過去並無直接關係。 比如天氣預測,如果我們知道“晴天,多雲,雨天”之間的轉換概率,那麼如果今天是晴天,我們就可以推斷出明天是各種天氣的概率,接著後天的天氣可以由明天的進行計算。這