八皇后 算法

看到有写这个的,所以自己写来练习一下,不过只是写到出结果,没有把所有的结果打印出来.

刚写的时候有些困难,后面步步细分,还是很好实现,主要是体现要分解来解决问题,下面是一坨C#的代码

    /// <summary>
    /// 八皇后问题解法
    /// 在网上看到有人写八皇后问题,今天写一个锻炼,保持对算法的感觉
    /// 2014-03-04
    /// 思想 动态规划,多分步骤
    /// </summary>
    public class EightQueen
    {
        private int QUEENNUM = 8;
        private int ROW = 8;
        private int COL = 8;
        private int[,] map;
        public EightQueen()
        {
            map = new int[ROW, COL];
            position = new List<Tuple<int, int>>[QUEENNUM];
            for (int i = 0; i < QUEENNUM; i++)
            {
                position[i] = new List<Tuple<int, int>>();
            }
        }
        #region 核心代码
        private List<Tuple<int, int>>[] position;
        //开始
        public void Start()
        {
            for (int i = 0; i < QUEENNUM; i++)
            {
                bool re = SetQueen(i);
                if (!re)
                {
                    ClearMap(i - 1);//清除地图
                    ClearPosition(i);//清除位置
                    i = i - 2;
                }
            }
        }
        //放下第num个皇后,true 正确放下 false 放不下
        private bool SetQueen(int num)
        {
            //棋盘上试
            for (int row = 0; row < ROW; row++)
            {
                for (int col = 0; col < COL; col++)
                {
                    if (IsSet(num, row, col))
                    {
                        map[row, col] = (num + 1);
                        LogPosition(num, row, col);
                        return true;
                    }
                }
            }
            return false;
        }
        //记录当前后已经试过的位置
        private void LogPosition(int num, int row, int col)
        {
            position[num].Add(new Tuple<int, int>(row, col));
        }
        //清空当前后位置信息
        private void ClearPosition(int num)
        {
            position[num].Clear();
        }
        //清除地图上的
        private void ClearMap(int num)
        {
            foreach (var a in position[num])
            {
                map[a.Item1, a.Item2] = 0;
            }
        }
        //当前位置是否可以放置后
        private bool IsSet(int num, int row, int col)
        {
            //试过的位置不能放
            foreach (var a in position[num])
            {
                if (a.Item1 == row && a.Item2 == col)
                    return false;
            }
            //没有放后的位置或被吃的位置可以放
            return map[row, col] == 0 && !InLine(row, col);
        }
        // true 线上有后了
        private bool InLine(int row, int col)
        {
            for (int i = 0; i < 8; i++)
            {
                //
                if (map[i, col] > 0)
                    return true;
                //
                if (map[row, i] > 0)
                    return true;
                ////+ +
                if (row + i < 8 && col + i < 8 && map[row + i, col + i] > 0)
                    return true;
                //+ -
                if (row + i < 8 && col - i >= 0 && map[row + i, col - i] > 0)
                    return true;
                //- +
                if (row - i >= 0 && col + i < 8 && map[row - i, col + i] > 0)
                    return true;
                //- -
                if (row - i >= 0 && col - i >= 0 && map[row - i, col - i] > 0)
                    return true;
            }
            return false;
        }
        #endregion
        // 显示棋盘数据
        public void Show()
        {
            for (int i = 0; i < ROW; i++)
            {
                for (int j = 0; j < COL; j++)
                {
                    Console.Write("{0} ", map[i, j]);
                }
                Console.WriteLine();
            }
        }
    }

总结

在思考复杂问题的时候尽量可以分细来处理,先把框架写出来,再写里面内容.像上面代码里的有几个方法,基本上就是一行代码为什么我还是分成了一个方法,为什么不在调用处用这一行代码呢?

这个就是之前思考留下的退迹,当然这样也会更好理解,因为我看到方法名我就知道这是一个什么步聚,但是一行代码不一定能读清楚.

    原文作者:八皇后问题
    原文地址: https://www.cnblogs.com/gw2010/p/3584346.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞