游客 Signup | Login
中文 | En

3966 - E. n皇后摆放问题

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。在n×n格的棋盘上,已经摆放好其它的一些棋子,皇后与皇后之间如果有棋子,就不能相互攻击,求出在n×n的棋盘上可以摆放最多的相互不能攻击的皇后数。

Input

首先输入nn<=4),然后输入n×n的棋盘,”X”表示已经摆放了的棋子,”.”表示棋盘空位。

Output

输出最多能摆放的皇后数。

Examples

Input

4
.X..
....
XX..
....
2
XX
.X
3
.X.
X.X
.X.
3
...
.XX
.XX
4
....
....
....
....

Output

4
1
2
2
4

Solution C++

//回溯法
#include<iostream>
#include<string>
using namespace std;
char map[4][4];
int best, n;
int place(int row, int col)
{
	int i;
	for (i = col - 1; i >= 0; i--){   //向左方向
		if (map[row][i] == 'X') break;
		if (map[row][i] == '1') return 0;
	}
	int j = col;
	for (i = row - 1; i >= 0; i--){   //左上方向
		j--;
		if (j<0) break;
		if (map[i][j] == 'X') break;
		if (map[i][j] == '1') return 0;
	}
	j = col;
	for (i = row - 1; i >= 0; i--){   //右上方向
		j++;
		if (j>n - 1) break;
		if (map[i][j] == 'X') break;
		if (map[i][j] == '1') return 0;
	}

	for (i = row - 1; i >= 0; i--){  //向上方向
		if (map[i][col] == 'X') break;
		if (map[i][col] == '1') return 0;
	}

	return 1;
}
void Backtrack(int t, int sum)
{
	if (t >= n*n){
		if (sum>best) best = sum;
		return;
	}
	int col, row;
	row = t / n; col = t%n;
	if (map[row][col] == '.'){
		if (place(row, col))
		{

			map[row][col] = '1'; //放炮后,递归
			Backtrack(t + 1, sum + 1);
			map[row][col] = '.';//不放炮,递归
		}
	}
	Backtrack(t + 1, sum);
}

int main()
{
	while (cin >> n)
	{
		int i;
		int j;
		for (i = 0; i < n; i++)
		for (j = 0; j < n; j++)
			cin >> map[i][j];
		best = 0;
		Backtrack(0, 0);
		cout << best << endl;
	}
	return 0;
}

Time Limit 1 second
Memory Limit 128 MB
Discuss Stats
上一题 下一题