POJ1321(DFS深搜)

Description
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
Input
输入含有多组测试数据。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
Output
对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。

题意:给你一个棋盘,‘#’位置可以摆放棋子,其他位置不可以摆放棋子。给你棋盘状态和需要摆放的棋子个数,问你总共有多少种棋子的摆法,其中,同一行或者同一列最多只能摆放2个棋子。

题解:用DFS搜索每一行的可以摆放的方案,具体方法代码里有解释。

思考:
1、如果想要跳过一行,直接dfs(a + 1, b)即可。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
const int maxn = 10 + 5;
char key[maxn][maxn];
int col[maxn];//用一个数组存储哪些列已经被放过
int n, k, c, m;

void dfs(int a, int b)
{
    if (b == 0) {//如果已经放完,就把种数加上
        c++;
        return;
    }
    if (b < 0 || a >= n) return;//dfs终止条件
    for (int i = 0; i < n; i++) {
        if (key[a][i] == '#' && col[i] == 0) {
            col[i] = 1;//把这一列标记上,相当于放上了棋子
            dfs (a + 1, b - 1);//从下一行开始dfs剩下的棋子
            col[i] = 0;//取消标记,防止对其他列造成影响
        }
    }
    dfs (a + 1, b);//从第a+1行开始放棋子,把a行跳过
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen ("in.txt", "r", stdin);
    #endif // ONLINE_JUDGE
    while (scanf ("%d%d", &n, &k) != EOF) {
        if (n == -1 && k == -1) break;
        memset (key, '/0', sizeof(key));
        memset (col, 0, sizeof(col));
        c = 0;
        m = 0;
        for (int i = 0; i < n; i++) {
            scanf ("%s", key[i]);
        }
        dfs (0, k);
        printf ("%d\n", c);
    }
    return 0;
}

你可能感兴趣的:(acm水题)