【POJ】1321-碁盤問題(dfs)

1977 ワード

碁盤問題
Time Limit: 1000MS
 
Memory Limit: 10000K
Total Submissions: 32058
 
Accepted: 15914
Description
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

Source
蔡錯@pku
dfs検索でいいので、難しくはありません.
コードは次のとおりです.
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int m,p;		//             
int ans;
char map[22][22];
int used[10];		//         (      ,   dfs          ) 
struct node
{
	int x,y;		//x  ,y   
}l[66];		//         

void dfs(int x,int y,int n)
{
	if (n == p)
	{
		ans++;
		return;
	}
	if (x == m-1)
		return;		//                ,      ,  !
	for (int i = x+1 ; i < m ; i++)
	{
		for (int j = 0 ; j < m ; j++)
		{
			if (map[i][j] == '#' && used[j] != 1)		//                
			{
				used[j] = 1;
				dfs(i,j,n+1);
				used[j] = 0;
			}
		}
	}
}

int main()
{
	while (~scanf ("%d %d",&m,&p) && (m != -1 || p != -1))
	{
		memset (used,0,sizeof (used));
		int num = 1;
		for (int i = 0 ; i < m ; i++)
		{
			scanf ("%s",map[i]);
			for (int j = 0 ; j < m ; j++)
			{
				if (map[i][j] == '#')
				{
					l[num].x = i;
					l[num++].y = j;
				}
			}
		}
		num--;
		ans = 0;
		for (int i = 1 ; i <= num ; i++)
		{
			used[l[i].y] = 1;
			dfs (l[i].x,l[i].y,1);
			used[l[i].y] = 0;
		}
		printf ("%d
",ans); } return 0; }