POJ 1321 簡單搜尋 回溯法 類n皇后問題
阿新 • • 發佈:2019-01-07
要求:在一個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,請程式設計求解對於給定形狀和大小的棋盤,擺放k個棋子的所有可行的擺放方案C。
方法:回溯法
1.深搜函式的引數為行數。
2.used[i]=1表示第i列已擺棋子,這樣可以減少搜尋一列是否會衝突。
3.一行放一個,然後搜尋下一行,這樣可以減少搜尋一行是否會衝突。
4.記得放一個棋子,記錄個數。
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #define inf 0x3f3f3f3f using namespace std; int n , k ; int num ; int cnt ; char map1[10][10] ; int used[10] ;//標記一列是否用過 bool canplace(int x ,int y) { int i , j ; int flag = 1 ; for(i = 0 ; i < x ; i ++) if(map1[i][y] == '*') flag = 0 ; for(i = 0 ; i < y ; i ++) if(map1[x][i] == '*') flag = 0 ; return flag ; } void dfs(int row) { int i , j ; if(num == k) { cnt ++ ; return ; } if(row == n) return ; for(i = 0 ; i < n ; i ++)//一行放一個 { if(used[i] == 0 && map1[row][i] == '#') { used[i] = 1 ; num ++ ; dfs(row + 1) ; used[i] = 0 ; num -- ; } } dfs(row + 1) ;//有時候上面的for迴圈會一個都放不了導致無法到達下一層 } int main() { int i , j ; char s[10] ; while(scanf("%d%d" , &n , &k) && !(n == -1 && k == -1)) { for(i = 0 ; i < n ; i ++) { scanf("%s" , &s) ; for(j = 0 ; j < n ; j ++) map1[i][j] = s[j] ; } num = 0 ; cnt = 0 ; memset(used , 0 , sizeof(used)) ; dfs(0) ; printf("%d\n" , cnt) ; } }