Алгоритм турнирной таблицы C алгоритм - PullRequest
0 голосов
/ 05 мая 2018

Мне нужно создать программу C , которая создает / генерирует таблицу расписаний турниров "друг против друга".
Всего 16 команд (от 1 до 16 номеров) и 15 туров. Таблица должна содержать раунд, в котором i-я и j-я команды играют друг против друга, и должен представлять собой двумерный массив, показанный в строках и столбцах (см. Ниже).
Также, если i == j, то a [i] [j] = 0, потому что ни одна команда не играет против себя ни в одном раунде.

Условия задачи мне не очень понятны.
Выше я объяснил, как я это понимаю.
Тем не менее, после нескольких часов Googling это похоже на турнир по круговому турниру.

Я думаю, это должно выглядеть так:

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. Другими словами Мне кажется, что первая строка смещается влево, но это не помогает мне придумать алгоритм.

1 Ответ

0 голосов
/ 05 мая 2018

Используйте это для заполнения массива:

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
...