zoukankan      html  css  js  c++  java
  • [算法]循环赛日程表

    问题描述:

    设有n=2k个运动员要进行网球循环赛。现要设计一个满足以下要求的比赛日程表:

    1. 每个选手必须与其他n-1个选手各赛一次;
    2. 每个选手一天只能参赛一次;
    3. 循环赛在n-1天内结束。

    请按此要求将比赛日程表设计成有n行和n-1列的一个表。在表中的第i行,第j列处填入第i个选手在第j天所遇到的选手。其中1≤i≤n,1≤j≤n-1。

    -------------------------------------------------------------------------

    解答:

    这个算法被划分到了分治算法的例子,的确它包含分治算法的意思,但是如果从构建规则出发,而不是从分治思想出发,我怎么感觉想起来更不绕弯呢!

    其实这个表的构建很容易。首先有个数组T,n行n列,第一列第一行填入数字1,初始就是这个样子的。

    1

    此时k=0,由它向下扩展,向右扩展,向右下扩展就变成了k=1的情况,即由一行一列变成二行而列,如何扩展呢?

    向下:原始值(左上角)加1(k)向下搬

    右上:把刚才填充上的左下的搬上去

    右下:把原来的,左上的搬下去。

    1

    2

     

    2

    1

     
         

    按照这个规律,当K=2的时候,应该是这个样子的

    1

    2

    3

    4

     

    2

    1

    4

    3

     

    3

    4

    1

    2

     

    4

    3

    2

    1

     
             

    当K=3的时候,应该是这个样子的

    1

    2

    3

    4

    5

    6

    7

    8

    2

    1

    4

    3

    6

    5

    8

    7

    3

    4

    1

    2

    7

    8

    6

    6

    4

    3

    2

    1

    8

    7

    5

    5

    5

    6

    7

    8

    1

    2

    3

    4

    6

    5

    8

    7

    2

    1

    4

    3

    7

    8

    5

    6

    3

    4

    1

    2

    8

    7

    6

    5

    4

    3

    2

    1

    把第一列去掉就是我们想要的8个运动员的比赛日程表。

    想通了,代码就非常容易了。

    /// <summary>
            /// 生成比赛日程表
            /// </summary>
            /// <param name="k">运动员数为2的n次方</param>
            public void GenerateTable(int n)
            {
                int N=(int)Math.Pow(2,n);
                int[,] T=new int[N,N];
                T[0, 0] = 1;
                for (int k = 0; k < n; k++)
                {
                    int end=(int)Math.Pow(2,k)-1;  //左上小方块结束的行和列
                    int end2 = (int)Math.Pow(2,k+1) - 1; //本次填充结束的行和列
                    int baseNum = (int)Math.Pow(2,k); 
                    //左下填充
                    for (int i = end + 1; i <= end2; i++)
                    {
                        for (int j = 0; j <= end; j++)
                        {
                            T[i, j] = T[i - baseNum, j] + baseNum;
                        }
                    }
                    //右上填充
                    for (int i = 0; i <= end; i++)
                    {
                        for (int j = end + 1; j <= end2; j++)
                        {
                            T[i, j] = T[i + baseNum, j - baseNum];
                        }
                    }
                    //右下填充
                    for (int i = end + 1; i <= end2; i++)
                    {
                        for (int j = end + 1; j <= end2; j++)
                        {
                            T[i,j]=T[i-baseNum,j-baseNum];
                        }
                    }
                }
                //output
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < N; i++)
                {
                    for (int j = 1; j < N; j++)
                    {
                        sb.Append(T[i,j]+" ");
                    }
                    sb.Append("
    ");
                }
                Console.WriteLine(sb);
                Console.ReadKey();
    
            }
    

      

  • 相关阅读:
    MYSQL实战-------丁奇(极客时间)学习笔记
    java并发编程实践——王宝令(极客时间)学习笔记
    分布式锁-----秒杀系统
    MYSQL IN 出现的慢查询问题
    携程2018年年度技术合集
    MySQL分库分表
    Mysql 千万级别数据数据查询
    视频协议融合平台人脸识别/车牌识别平台EasyCVR内调用接口二次开发疑难解答
    国标GB28181/Ehone协议视频人脸识别/车牌识别平台EasyCVR新版本支持大华SDK接入开发记录
    国标GB28181协议接入视频智能分析平台EasyCVR的设备用ws_flv为什么会有无法播放的情况?
  • 原文地址:https://www.cnblogs.com/orchid/p/3275747.html
Copyright © 2011-2022 走看看