我需要做一个C程序来创建/生成一个赛程表来“互相对抗”。
一共有16个队(1到16个号码)和15轮该表应包含i-th和j-th团队相互对抗的回合,并且必须是以行和列显示的2D数组(见下文)。
同样,如果i==j,那么a[i][j]=0,因为没有一支球队在任何一轮中与自己比赛。
任务的条件我不太清楚。
我已经解释了以上我的理解方式。
然而,在数小时的谷歌搜索之后,似乎基本上是一场循环赛。
我想应该是这样的:
teams 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
2 1 0 3 4 5 6 7 8 9 10 11 12 13 14 15 2
3 2 3 0 5 6 7 8 9 10 11 12 13 14 15 1 4
4 3 4 5 0 7 8 9 10 11 12 13 14 15 1 2 6
5 4 5 6 7 0 9 10 11 12 13 14 15 1 2 3 8
6 5 6 7 8 9 0 11 12 13 14 15 1 2 3 4 10
7 6 7 8 9 10 11 0 13 14 15 1 2 3 4 5 12
8 7 8 9 10 11 12 13 0 15 1 2 3 4 5 6 14
9 8 9 10 11 12 13 14 15 0 2 3 4 5 6 7 1
10 9 10 11 12 13 14 15 1 2 0 4 5 6 7 8 3
11 10 11 12 13 14 15 1 2 3 4 0 6 7 8 9 5
12 11 12 13 14 15 1 2 3 4 5 6 0 8 9 10 7
13 12 13 14 15 1 2 3 4 5 6 7 8 0 10 11 9
14 13 14 15 1 2 3 4 5 6 7 8 9 10 0 12 11
15 14 15 1 2 3 4 5 6 7 8 9 10 11 12 0 13
16 15 2 4 6 8 10 12 14 1 3 5 7 9 11 13 0
我不知道从哪里开始,我唯一能做的就是用零填充主对角线。
这是我的代码,但是表的输出不太好:
#include<stdio.h>
void print(int a[16][16]);
void schedule(int a[16][16]);
void main(){
int a[16][16], i, j;
schedule(a);
print(a);
}
void schedule(int a[16][16]){
for (int i = 0; i < 16; i++){
for (int j = 0; j < 16; j++)
if (i == j)
a[i][j] = 0;
}
}
void print(int a[16][16]){
int k = 0;
printf("teams: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16\n");
for (int i = 0; i < 16; i++){
k++;
if (i < 10)
printf(" %d ", k);
if (i >= 10)
printf(" %d ", k);
for (int j = 0; j < 16; j++){
if (a[i][j] == 0 && j < 10){
printf("%d ", a[i][j]);
}
else if (a[i][j] == 0 && j >= 10) {
printf(" %d ", a[i][j]);
}
if (j < 10)
printf(" ");
else
printf(" ");
}
printf("\n");
}
}
从表中(按行或列)我注意到,数字通常在
a[i][0]
中的数字之前,在行的末尾+数字“覆盖”为0换句话说,在我看来,第一行是向左移动的,但这无助于我想出一个算法。 最佳答案
用于填充数组:
const int NofTeams=16;
int a[NofTeams][NofTeams];
int i,j;
for(i = 0; i< NofTeams-1; i++)
{
for(j =0; j < NofTeams-1; j++)
{
if(i==j)
{
/* edge cases */
a[i][NofTeams-1]=((i+j)+(i+j)/NofTeams)%NofTeams;
a[NofTeams-1][j]=((i+j)+(i+j)/NofTeams)%NofTeams;
a[i][j]=0;
} else
{
a[i][j]=((i+j)+(i+j)/NofTeams)%NofTeams;
}
}
}
/* corner cases; [0][0] is diagonal */
a[0][NofTeams-1]=NofTeams-1;
a[NofTeams-1][NofTeams-1]=0;
a[NofTeams-1][0]=NofTeams-1;
诀窍在于序列
((i+j)+(i+j)/NofTeams)%NofTeams
。这是为了永远不要打印太高的整数(最大的是减1个队):
%NofTeams
。这是为了增加团队的数量(在
%
之后,最终成为不需要的0
):+(i+j)/NofTeams
。这是与其他项目相结合的基本循环:
(i+j)
(两者中的第一个)。否则,诀窍就是只用循环填充非边的情况,并具体地做边的情况,即基本的制表概念。
输出(简单的二维表格打印,第一行和第一列根据您所需的输出):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
2 1 0 3 4 5 6 7 8 9 10 11 12 13 14 15 2
3 2 3 0 5 6 7 8 9 10 11 12 13 14 15 1 4
4 3 4 5 0 7 8 9 10 11 12 13 14 15 1 2 6
5 4 5 6 7 0 9 10 11 12 13 14 15 1 2 3 8
6 5 6 7 8 9 0 11 12 13 14 15 1 2 3 4 10
7 6 7 8 9 10 11 0 13 14 15 1 2 3 4 5 12
8 7 8 9 10 11 12 13 0 15 1 2 3 4 5 6 14
9 8 9 10 11 12 13 14 15 0 2 3 4 5 6 7 1
10 9 10 11 12 13 14 15 1 2 0 4 5 6 7 8 3
11 10 11 12 13 14 15 1 2 3 4 0 6 7 8 9 5
12 11 12 13 14 15 1 2 3 4 5 6 0 8 9 10 7
13 12 13 14 15 1 2 3 4 5 6 7 8 0 10 11 9
14 13 14 15 1 2 3 4 5 6 7 8 9 10 0 12 11
15 14 15 1 2 3 4 5 6 7 8 9 10 11 12 0 13
16 15 2 4 6 8 10 12 14 1 3 5 7 9 11 13 0
关于c - 比赛调度表C算法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50186119/