保龄球Split算法

发布时间 2023-06-30 17:02:52作者: xl_code

需求:

  1. 剩下两个或两个以上的球瓶它们之间没有球瓶; 例如: 7-9 或者 3-10
  2. 剩下两个或两个以上的球瓶,他们前面的球瓶被击倒,例如: 5-6

保龄球位置信息如下图:  

 

        private int SplitBall(string positionStr)
        {
            //第一个球必须倒并且未倒的球大于1个
            if (positionStr[0] == '0' && positionStr.Select(o => o == '1').Count() > 1)
            {
                //数组columnIdx[i]表示第i个球所在列的索引,索引从0开始[1,2,3,4,5,6,7,8,9,10],参考注释中的位置图
                int[] columnIdx = { 3, 2, 4, 1, 3, 5, 0, 2, 4, 6 };
                //每列几个球,参考注释中的位置图
                int[] columnBallCount = { 1, 1, 2, 2, 2, 1, 1 };
                for (int i = 0; i < positionStr.Length; i++)//更新每一列现存的球个数
                {
                    if (positionStr[i] == '0')//当前列每击倒一球count-1
                    {
                        //表示第i个球所在的第数组columnIdx[i]列的球的个数columnBallCount[数组columnIdx[i]]减1
                        columnBallCount[columnIdx[i]]--;
                    }
                }
                //两列中的前一列
                for (int i = 0; i < columnBallCount.Length; i++)
                {
                    //两列中的后一列
                    for (int j = i + 1; j < columnBallCount.Length; j++)
                    {
                        //如果出现两列各自现存的球的个数都不为0
                        if (columnBallCount[i] != 0 && columnBallCount[j] != 0)
                        {
                            //遍历这两列中间的列
                            for (int k = i + 1; k < j; k++)
                            {
                                //中间列被击倒的情况就是split
                                if (columnBallCount[k] == 0)
                                {
                                    return 1;
                                }
                            }
                        }
                    }
                }
            }
            return 0;
        }