我需要做一个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/

10-12 04:23