1. 程式人生 > >POJ 1321 棋盤問題(簡單DFS)

POJ 1321 棋盤問題(簡單DFS)

clas mission sample 標記 span ssi algo std spa

                                                          棋盤問題
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 45545 Accepted: 22035

Description

在一個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,請編程求解對於給定形狀和大小的棋盤,擺放k個棋子的所有可行的擺放方案C。

Input

輸入含有多組測試數據。
每組數據的第一行是兩個正整數,n k,用一個空格隔開,表示了將在一個n*n的矩陣內描述棋盤,以及擺放棋子的數目。 n <= 8 , k <= n
當為-1 -1時表示輸入結束。
隨後的n行描述了棋盤的形狀:每行有n個字符,其中 # 表示棋盤區域, . 表示空白區域(數據保證不出現多余的空白行或者空白列)。

Output

對於每一組數據,給出一行輸出,輸出擺放的方案數目C (數據保證C<2^31)。

Sample Input

2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1

Sample Output2

1

一定要理解DFS的原理及思想!
#include<iostream>
#include<algorithm>
using namespace std;
bool col[9], maze[9][9];
int n, k,ans;
void dfs(int row, int num)
{
    if (num == k)
    {
        ans++;
        return;
    }
    if (row > n)//避免搜索越界
        return;
    for (int i = 1; i <= n; i++)
    {
        
if (maze[row][i] && !col[i])//當前列未被搜索過 { col[i] = true;//標記 dfs(row + 1, num + 1);//對當前行落一顆子,向下一行搜索 col[i] = false;//DFS回溯後,對當前列狀態復原 } } dfs(row + 1, num);//當k<n時,row沒到最後一行時就可能已經把全部棋子放好了 //因此為了處理後面的行,可以讓當前位置先不放棋子,然後再對下一行DFS return; } int main() { while (cin >> n >> k) { if (n == -1 && k == -1) break; ans = 0; memset(maze, false, sizeof(maze));//輸入的數據有多組,所以初始化很重要 memset(col, false, sizeof(col)); for(int i=1;i<=n;i++) for (int j = 1; j <= n; j++) { char c; cin >> c; if (c == #) maze[i][j] = true; } dfs(1, 0);//起點狀態 cout << ans << endl; } return 0; }

 

POJ 1321 棋盤問題(簡單DFS)