看到有写这个的,所以自己写来练习一下,不过只是写到出结果,没有把所有的结果打印出来.
刚写的时候有些困难,后面步步细分,还是很好实现,主要是体现要分解来解决问题,下面是一坨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(); } } }
总结
在思考复杂问题的时候尽量可以分细来处理,先把框架写出来,再写里面内容.像上面代码里的有几个方法,基本上就是一行代码为什么我还是分成了一个方法,为什么不在调用处用这一行代码呢?
这个就是之前思考留下的退迹,当然这样也会更好理解,因为我看到方法名我就知道这是一个什么步聚,但是一行代码不一定能读清楚.