kuangbin專題一 簡單搜尋 棋盤問題
阿新 • • 發佈:2021-02-01
技術標籤:題目
棋盤問題
題目連結
https://vjudge.net/problem/POJ-1321
題目描述
在一個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,請程式設計求解對於給定形狀和大小的棋盤,擺放k個棋子的所有可行的擺放方案C。
輸入格式
輸入含有多組測試資料。
每組資料的第一行是兩個正整數,n k,用一個空格隔開,表示了將在一個n*n的矩陣內描述棋盤,以及擺放棋子的數目。 n <= 8 , k <= n
當為-1 -1時表示輸入結束。
輸出格式
對於每一組資料,給出一行輸出,輸出擺放的方案數目C (資料保證C<2^31)。
輸入樣例
2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1
輸出樣例
2
1
解題思路
通過行進行搜尋,在搜尋的過程中對列進行迴圈,這樣就可以保證同行同列不會有重複的棋子落下,在所有的棋子落下之後,說明該方案可行,然後進行回溯更改位置,再次進行搜尋
AC 程式碼
小白記錄成長,歡迎各路大佬前來教學
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
#include <string>
using namespace std;
const int N = 15;
int n, m;
char maze[N][N];// 記錄地圖
bool mark[N];// 標記陣列,對每一列進行標記
int cnt, cnt_2;//cnt 用於記錄放置的棋子的數量, cnt_2 用於記錄總方案數
void dfs( int x )
{
if(cnt == m)// 如果所有的棋子都放置了,說明情況可行,則方案數 +1
{
cnt_2 ++;
return ;
}
else if ( x >= n )//說明擺放越界,直接 return 即可
{
return ;
}
else
{
for(int i = 0 ; i < n ; i ++ )
{
if( !mark[i] && maze[x][i] == '#' ) // 如果沒有標記,並且圖中為 “#” 說明該點可以放置
{
mark[i] = true; // 將該列的標記置為 true ,表示該列不可再放置
cnt++; // 放置一個棋子,cnt ++
dfs( x + 1 ); // 以下一行開始進行遍歷
mark[i] = false; // return 之後消除標記
cnt--;// 同時消除該行棋子
}
}
}
dfs( x + 1 );// x 行不放置棋子
}
int main ( int argc, char* argv [ ] )
{
while(cin >> n >> m)
{
if( n == -1 && m == -1 )
break;
memset(mark,false,sizeof(mark));
cnt = 0;
cnt_2 = 0;
for( int i = 0; i < n ; i ++ )
{
for( int j = 0; j < n ; j ++ )
{
cin >> maze[i][j];
}
}
dfs(0);
cout<<cnt_2<<endl;
}
return 0;
}