题目描述
*的每间牢房是一个不超过4×4的正方形,里面设有一些障碍,牢房里住着的犯人脾气都很大,只要两个犯人位于同一行或同一列即会发生冲突,但障碍物可以阻挡同行或同列犯人的冲突。问最多可放几个犯人而不会发生冲突。如图2.18所示,左边表示初始牢房样,右边4个显示了摆放方案,当然,最后两个方案是错误的。
输入格式:
有多组测试数据,每组数据第一行为一个整数N表示牢房大小。随后N行描述牢房,其中X表示障碍。
所有测试数据结束的标志为0。
输出格式:
输出最多可放的犯人数。
输入样例
4 .X.. .... XX.. .... 3 .X. X.X .X. 3 ... .XX .XX 0
输出样例
5 5 2
思路
这题所给的数据范围很小,DFS直接暴力搜索就完了。
代码
#include <iostream>
using namespace std;
void dfs(int p,int cnt);
int n;
char s[6][6];
int best;
int main()
{
while(cin >> n && n)
{
best = 0;
for(int i = 0; i < n; i++)
{
cin >> s[i];
}
dfs(0, 0);
cout << best << endl;
}
return 0;
}
void dfs(int p,int cnt)
{
if(p == n * n)
//更新历史最佳答案
{
best = max(best, cnt);
return ;
}
int x = p / n;
int y = p % n;
dfs(p + 1, cnt); //这个是不放囚犯的
if(s[x][y] == '.')
//暴力搜索有没有不符合条件的
{
int op = 1;
for(int i = x; i < n; i++)
{
if(s[i][y] == 'X')
{
break;
}
if(s[i][y] == 'M')
{
op = 0;
}
}
for(int i = x; i >= 0; i--)
{
if(s[i][y] == 'X')
{
break;
}
if(s[i][y] == 'M')
{
op = 0;
}
}
for(int i = y; i < n; i++)
{
if(s[x][i] == 'X')
{
break;
}
if(s[x][i] == 'M')
{
op = 0;
}
}
for(int i = y; i >= 0; i--)
{
if(s[x][i] == 'X')
{
break;
}
if(s[x][i] == 'M')
{
op = 0;
}
}
if(op == 1)
//如果op还是1的话,说明可以放囚犯
{
//犯了囚犯给他 MARK 一下,下一次不能再放在这里
s[x][y] = 'M';
//下一层
dfs(p + 1, cnt + 1);
//恢复现场
s[x][y] = '.';
}
}
}