[POJ-1321]棋盤問題


題目描述

在一個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,請編程求解對於給定形狀和大小的棋盤,擺放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 Output

2
1

題目分析:

dfs模板題。棋盤上的每一個格子都有放或者不放兩種可能,把放和不放看成兩種操作,那么就成了一個二叉樹,接下來的操作就是相當於先序遍歷這顆二叉樹。

引用:先序遍歷二叉樹的偽代碼:

void PreOrderTraverse(BiTree T)
{
    if(T == NULL) return;
    printf("%d",T->data);
    PreorderTraverse(T->lchild);
    PreorderTraverse(T->rchild);
}

AC代碼:

#include<iostream>
#include<cstdio>

using namespace std;

const int N = 100;
bool col[N],row[N];
char g[N][N];
int cnt = 0,n,m;
void dfs(int x,int y,int k)
{
    if(x == n) return;
    if(k == m) 
    {
        cnt++;
        return;
    }
    if(y == n)
    {
        y = 0;
        x++;
    }
    dfs(x,y+1,k);//先遞歸遍歷左子樹,即不放皇后的操作
    if(!col[y]&&!row[x]&&(g[x][y] == '#'))
    {
        col[y] = row[x] = true;
        <!--dfs(x,y+1,k+1);//再遞歸遍歷右子樹
        col[y] = row[x] = false;
    }
}
int main()
{
    while(1)
    {
        scanf("%d%d",&n,&m);
        if(n == -1&&m == -1) break;
        for(int i = 0;i<n;i++)
            for(int j = 0;j<n;j++)
                cin>>g[i][j];
        dfs(0,0,0);
        printf("%d\n",cnt);
        cnt = 0;
    }
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM