1243 迴圈賽日程表

2021-07-04 07:28:14 字數 1365 閱讀 9475

時限:1000ms 記憶體限制:10000k 總時限:3000ms

描述 用分治演算法生成迴圈賽日程表(1到2的n次方個人)

輸入 乙個整數n

輸出 迴圈賽日程表(1到2的n次方個人)

輸入樣例

3輸出樣例

1 2 3 4 5 6 7 8

2 1 4 3 6 5 8 7

3 4 1 2 7 8 5 6

4 3 2 1 8 7 6 5

5 6 7 8 1 2 3 4

6 5 8 7 2 1 4 3

7 8 5 6 3 4 1 2

8 7 6 5 4 3 2 1

分析:

採用分治演算法,把乙個問題分為四個子問題,即乙個**平均劃分為四個**,其中右下角與左上角完全相同,右上角與左下角完全相同,所以在該問題中,只用算出左上角和左下角的表或右上角和右下角的表再複製即可。

#include 

using

namespace

std;

int n;

int a[10000][10000];

void table(int k,int m)

else

for(i=k-1;i1+m/2;i++) //右上的**中元素與左下的相等

for(j=m/2;j2][j-m/2];

for(i=k-1+m/2;i1+m;i++) //右下的**中元素與左上的相等

for(j=m/2;j2][j-m/2];

}int main()

需要注意的是,在複製的過程中,行和列for迴圈的條件是不同的

for(i=k-1;i

1+m/2;i++)

for(j=m/2;j

j++)

a[i]

[j]=a[i+m/2]

[j-m/2];

如左下複製給右上時,行是從第k-1個開始,而列始終從m/2開始即可

這是因為,在n=3的情況下

遞迴呼叫table的順序是

table(1,4)

→table(1,2)

→table(3,2)

table(5,4)

→table(5,2)

→table(7,2)

然後m=2,給定第一列每個元素乙個值

再複製給第二列

由此可以觀察出,此遞迴呼叫的執行順序是,先給第一列每乙個元素乙個初值,然後大體上按從左到右的順序依次給每一列的元素賦值,而每一列元素獲得值的具體實現又是按照左上=右下,左下=右上,對角線的方法得到的

故行的下標跟k值息息相關,而列按照大體上從左到右的順序即可,與k無關

NOJ 1243 迴圈賽日程表

時限 1000ms 記憶體限制 10000k 總時限 3000ms 描述用分治演算法生成迴圈賽日程表 1到2的n次方個人 輸入乙個小於等於7的正整數n 輸出迴圈賽日程表 1到2的n次方個人 輸入樣例 輸出樣例 1 2 3 4 5 6 7 8 2 1 4 3 6 5 8 7 3 4 1 2 7 8 5...

迴圈賽日程表

對於書上那個日程表的實現,第三版的課本給出了迴圈實現的方法,不過這個表的生成明顯要用遞迴方法生成更為合適,此表如下 可以看到每次該錶的生成總可以分成四個字表的填充過程,初始化讓左邊第一列填充上之後,然後每一次先遞迴填充左上角的子表,然後再填充左下角的子表,然後右上和右下的子表用copy的方法填充,實...

迴圈賽日程表

設有n個選手進行迴圈比賽,其中n 2 m,要求每名選手要與其他n 1名選手都賽一次,每名選手每天比賽一次,迴圈賽共進行n 1天,要求每天沒有選手輪空。輸入第一行為t,表示資料組數,對於每組資料就乙個m 1 m 10 對於每組輸入的m,輸出 形式的比賽安排表 1 3 1 2 3 4 5 6 7 8 2...