C#中的循环赛事算法

Pol*_*olo 7 c# algorithm round-robin

我在实现这个小循环项目时遇到了一些麻烦.我尝试做的是生成游戏的预览日历

那我想输出;

第1天:第1队与第2队; 第3队与第4队; Team 5vs Team 6;

第2天第1队与第4队; 第6队与第3队; 第2队与第5队;

直到锦标赛结束;

这是我到目前为止所获得的代码,但是我很难让第一个团队修复而阵列的其余部分旋转......:

static void Main(string[] args)
   {
        string[] ListTeam = new string[] {"Equipe1", "Equipe2", "Equipe3", "Equipe4", "Equipe5", "Equipe6"};
        IList<Match> ListMatch = new List<Match>();
        it NumberOfDays = (ListTeam.Count()-1);
        int y = 2;

        for (int i = 1; i <= NumberOfDays; i++)
        {
            Console.WriteLine("\nDay {0} : \n",i);
            Console.WriteLine(ListTeam[0].ToString() + " VS " + ListTeam[i].ToString());

            for (y =ListTeam.Count(); y>0 ; y--)
            {
                Console.WriteLine(ListTeam[y].ToString() + " VS " + ListTeam[y+1].ToString());
                y++;
            }

        }
    }
Run Code Online (Sandbox Code Playgroud)

编辑:我在java中找到了一个代码示例,但我无法翻译它...

par*_*cle 11

这应该很容易使用模运算:

更新2 :(正如承诺的正确算法)

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]);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这将打印每天的团队比赛.

让我快速尝试解释算法的工作原理:

我注意到,因为除了第一个团队之外我们正在轮换所有团队,如果我们将所有团队放在除第一个团队之外的数组中,那么我们应该根据当天使用索引偏移来读取该数组中的第一个团队模数运算正确包裹.在实践中,我们将该数组视为在两个方向上无限重复,我们将逐渐向右(或向左)滑动我们的视图.

然而,有一个障碍,那就是我们必须以非常特殊的方式订购团队才能使其正常工作.否则,我们无法获得正确的旋转.因此,我们需要以非常特殊的方式阅读匹配的第二个团队.

准备清单的正确方法如下:

  • 永远不要把第一个团队(团队#1)放在列表​​中.
  • 获取团队列表的后半部分并将它们放在列表的前面.
  • 取列表的前半部分,将其反转并将其放入列表中(但不是#1队).

现在,读取列表的正确方法如下:

  • 对于每一天,增加您正在查看的第一个索引1.
  • 对于您在该位置看到的第一个团队,请将该团队与团队#1进行匹配.
  • 对于列表中的下一个团队((day + idx) % numDays),我们通常将其与团队数量减去一半的团队减去1(减去1因为我们自己处理第一场比赛)相匹配.但是,由于我们列表的后半部分是通过还原来准备的,因此我们需要在列表的后半部分中匹配该偏移量.一种更简单的方法是观察到这相当于匹配相同的索引,但是从列表的末尾开始.给定当前的day偏移量(day + (numDays - idx)) % numDays.

更新3:我不满意我的解决方案涉及如此复杂的选择,匹配,反转数组元素.在我想到我的解决方案涉及到什么之后,我意识到我太过于担心保持团队的顺序.然而,这不是一项要求,人们可以通过不关心初始订购来获得不同但同样有效的时间表.重要的是我在解释的第二部分中描述的选择算法.

因此,您可以简化以下行:

teams.AddRange(ListTeam.Skip(halfSize).Take(halfSize));
teams.AddRange(ListTeam.Skip(1).Take(halfSize -1).ToArray().Reverse());
Run Code Online (Sandbox Code Playgroud)

至:

teams.AddRange(ListTeam); // Copy all the elements.
teams.RemoveAt(0); // To exclude the first team.
Run Code Online (Sandbox Code Playgroud)


bmm*_*m6o 6

听起来你想安排一场循环赛.wp文章包含算法.

我甚至没有看到你在哪里试图旋转阵列.排列看起来像:1 - > 2 - > 3 - > 4 ... - > n/2 - 1 - > n - 1 - > n - 2 - > n - 3 - > ... - > n/2 - > 1(0保持固定).您可以在2个循环(顶行和底行)中执行此操作.