标签:
Follow up for N-Queens problem.
Now, instead outputting board configurations, return the total number of distinct solutions.
首先需要确定什么位置放置皇后是合法的(满足同一行,同一列,同一对角线上不存在两个皇后,即为一种可行解),设两个皇后的位置为(x1,y1),(x2,y2),
限制条件为:x1 != x2(同一行不存在两个皇后)
y1 != y2(同一列不存在两个皇后)
x1 + y1 != x2 + y2(45度对角线上不存在两个皇后)
x1 - y1 != x2 - y2(135度对角线上不存在两个皇后)
public boolean valid(int h, int l) { //check column if(cols.contains(l)) return false; //check diagonal(45) if(diagonals1.contains(h+l)) return false; //check diagonal(135) if(diagonals2.contains(h-l)) return false; return true; }
使用回溯法分别给出递归和非递归的代码。
递归代码:
/*********************************************** * i 第i个皇后(即第i行) * total 表示n皇后问题解的个数 * n 皇后个数 ***********************************************/ public void totalNQueensRecursion(int i, int n) { for(int j=0; j<n; j++) { if(valid(i, j)) { if(i != n-1) { cols.add(j); diagonals1.add(i+j); diagonals2.add(i-j); totalNQueensRecursion(i+1, n); cols.remove(j); diagonals1.remove(i+j); diagonals2.remove(i-j); } else { total++; } } } }
非递归代码:
public int totalNQueens(int n) { int j = 0; for(int i=0; i<n; i++) { for(; j<n; j++) { if(valid(i, j)) { if(i != n-1) { cols.add(j); diagonals1.add(i+j); diagonals2.add(i-j); j = 0; break; } else { total++; continue; } } } //turn back if(j >= n) { for(i=i-1; i>=0; i--) { if(cols.get(i) < n-1) { j = cols.get(i) + 1; cols.remove(i); diagonals1.remove(i); diagonals2.remove(i); break; } else { cols.remove(i); diagonals1.remove(i); diagonals2.remove(i); } } if(i < 0) { return total; } i--;//抵消for循环中的i++; } } return total; }
在上述两段代码中,都使用的集合:
private List<Integer> cols = new ArrayList<Integer>(); private List<Integer> diagonals1 = new ArrayList<Integer>();//45度对角线,和相同 private List<Integer> diagonals2 = new ArrayList<Integer>();//135度对角线,差相同
标签:
原文地址:http://www.cnblogs.com/linxiong/p/4287756.html