To powinno być dość łatwe do zrobienia przy użyciu arytmetyki modularnej:
UPDATE 2: (Jak obiecał poprawny algorytm)
public void ListMatches(List<string> ListTeam)
{
if (ListTeam.Count % 2 != 0)
{
ListTeam.Add("Bye");
}
int numDays = (numTeams - 1);
int halfSize = numTeams/2;
List<string> teams = new List<string>();
teams.AddRange(ListTeam.Skip(halfSize).Take(halfSize));
teams.AddRange(ListTeam.Skip(1).Take(halfSize -1).ToArray().Reverse());
int teamsSize = teams.Count;
for (int day = 0; day < numDays; day++)
{
Console.WriteLine("Day {0}", (day + 1));
int teamIdx = day % teamsSize;
Console.WriteLine("{0} vs {1}", teams[teamIdx], ListTeam[0]);
for (int idx = 1; idx < halfSize; idx++)
{
int firstTeam = (day + idx) % teamsSize;
int secondTeam = (day + teamsSize - idx) % teamsSize;
Console.WriteLine("{0} vs {1}", teams[firstTeam], teams[secondTeam]);
}
}
}
które wydrukować każdy dzień mecze zespołu.
Pozwól mi szybko starają się wyjaśnić, jak działa algorytm:
Zauważyłem, że skoro jesteśmy obracając wszystkie zespoły z wyjątkiem pierwszego, jeśli stawiamy wszystkie zespoły w tablicy z wyjątkiem pierwszego, potem powinien po prostu odczytać pierwszy zespół z tej tablicy, używając przesunięcia indeksu opartego na danym dniu i wykonując modularną arytmetykę, aby poprawnie owijać. W praktyce traktowalibyśmy tę tablicę jako nieskończenie powtarzającą się w obu kierunkach, a my przesuwalibyśmy nasz widok stopniowo w prawo (lub w lewo).
Istnieje jednak jeden szkopuł, i to jest fakt, że musimy bardzo dokładnie zamówić zespoły, aby działały poprawnie. W przeciwnym razie nie otrzymamy prawidłowego obrotu. Z tego powodu musimy również czytać pasujący drugi zespół w bardzo osobliwy sposób.
Prawidłowy sposób na przygotowanie listy jest następujący:
- Nigdy umieścić pierwszego zespołu (Team # 1) na liście.
- Weź ostatnią połowę listy zespołów i umieść je na początku listy.
- Zrób pierwszą połowę listy, cofnij i umieść je na liście (ale nie w zespole nr 1).
Teraz poprawny sposób odczytać z listy jest następująca:
- Dla każdego dnia, przyrost pierwszy indeks patrzysz przez
1
.
- Dla pierwszego zespołu, który widzisz w tej lokalizacji, dopasuj tę drużynę do Drużyny nr 1.
- Dla następnej drużyny na liście (
(day + idx) % numDays
), normalnie dopasowalibyśmy ją do drużyny, która jest zrekompensowana o połowę liczbą drużyn minus 1 (minus 1, ponieważ sami poradziliśmy sobie z pierwszym meczem). Ponieważ jednak druga połowa naszej listy została przygotowana przez cofnięcie, musimy dopasować to przesunięcie w odwróconej drugiej połowie listy. Prostszym sposobem jest stwierdzenie, że jest to równoważne dopasowaniu tego samego indeksu, ale od końca listy. Biorąc pod uwagę aktualne przesunięcie day
, czyli (day + (numDays - idx)) % numDays
.
UPDATE 3: nie był zadowolony, że moje rozwiązanie udział takiego zwichrowanych wybór, dopasowywanie odwracania elementów macierzy. Po tym, jak zastanowiłem się nad tym, w czym znalazło się moje rozwiązanie, zdałem sobie sprawę z tego, że byłem zbyt roztropny, aby utrzymać porządek w drużynach, tak jak podałem. Jednak nie jest to wymagane i można uzyskać inny, ale równie ważny harmonogram, nie dbając o początkowe zamówienie. Liczy się jedynie algorytm doboru, który opisuję w drugiej części mojego wyjaśnienia.
W ten sposób można uprościć następujące linie:
teams.AddRange(ListTeam.Skip(halfSize).Take(halfSize));
teams.AddRange(ListTeam.Skip(1).Take(halfSize -1).ToArray().Reverse());
do:
teams.AddRange(ListTeam); // Copy all the elements.
teams.RemoveAt(0); // To exclude the first team.
Nie mogę znaleźć sposobu na załapanie pierwszego zespołu i nadal nie stosuję innych meczów. – Polo
@John Nolan: Przepraszam za literówki i pisownię ... – Polo
Implementacja Java, z którą się łączyłeś, jest bardzo niejasna. Również fakt, że tekst i zmienne są w języku francuskim, nie pomaga (przynajmniej ja). – paracycle