POJ-1321簡単な暴力捜査

1830 ワード

1つの所定の形状の碁盤(形状が不規則である可能性がある)の上に駒を並べ、駒に違いはない.並べ替え時に任意の2つの駒が碁盤の中の同一行または同一列に置かれないことを要求する場合は、所定の形状と大きさの碁盤に対してk個の駒を並べたすべての実行可能な並べ替えスキームCをプログラミングして解いてください.
Input
複数セットのテストデータを入力します. 
各グループのデータの最初の行は2つの正の整数、n kであり、1つのスペースで区切られ、1つのn*nのマトリクス内に碁盤を記述し、駒を置く数を示す.n <= 8 , k <= n 
-1-1の場合は入力が終了します. 
次のn行は、各行にn文字を有する碁盤の形状を示す.空白領域を表します(データは余分な空白行や空白列が現れないことを保証します).
Output
各セットのデータに対して、1行の出力が与えられ、配置されたシナリオ数Cが出力される(データ保証C<2^31).
Sample Input
2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1
Sample Output
2

1
一つの中国語の水体は、提案から暴力DFSであることがわかりますが、私はまだ水が多すぎて、dfsだと知っているだけで本当にどのように叩くか分かりません.再帰的にずっと理解があいまいなので、最近ずっとDFSの問題をしたいと思っています.だから、まずこの大水問題から始めましょう.違う大物のブログを見てやっと分かりました.
構想:最初の行から遍歴して、もしこの地方が駒を置くことができるならば、マークの下で、遍歴の下の、もし置く駒が要求の個数に達するならば直接return、1つのグローバル変数で一致する方式を保存します.
コードは次のとおりです.
#include 
#include 
#include 
#include 
using namespace std;
char s[30][30];
bool vis[30];
int sum, m, n;
void dfs(int x, int num)
{
    if(num == n)
    {
        sum++;
        return;
    }
    else
    {

    for(int i = x; i < m; i++)  //                #
        for(int j = 0; j < m; j++)
            if(s[i][j] == '#' && !vis[j])
    {
        vis[j] = 1;
        dfs(i + 1, num + 1);
        vis[j] = 0;
    }
}
}
int main()
{
    while(scanf("%d%d", &m, &n) != EOF)
    {
        memset(s, 0, sizeof(s));
        memset(vis, 0, sizeof(vis));
        sum = 0;
        getchar();
        if(m == -1 && n == -1)
            break;
        for(int i = 0; i < m; i++)
            scanf("%s", s[i]);
        dfs(0, 0); //        
        cout << sum << endl;
    }
    return 0;
}