NOJ堡垒问题
描述:
城堡是一个4×4的方格,为了保卫城堡,现需要在某些格子里修建一些堡垒。城堡中的某些格子是墙,其余格子都是空格,堡垒只能建在空格里,每个堡垒都可以向上下左右四个方向射击,如果两个堡垒在同一行或同一列,且中间没有墙相隔,则两个堡垒都会把对方打掉。问对于给定的一种状态,最多能够修建几个堡垒。
输入:
每个测例以一个整数n(1<=n<=4)开始,表示城堡的大小。接下来是n行字符每行n个,‘X’表示该位置是墙,‘.’表示该位置是空格。n等于0标志输入结束。
输出:
每个测例在单独的一行输出一个整数:最多修建堡垒的个数。
输入样例:
4
.X…
…
XX…
…
2
XX
.X
3
.X.
X.X
.X.
3
…
.XX
.XX
4
…
…
…
…
0
输出样例:
5
1
5
2
4
#include<iostream>
using namespace std;
int n;//城堡大小
int Mark[5][5];
int maxN, tempN;
bool canplace(int, int);
void search(int);
int main()
{
while (cin >> n){
char x;
if (n == 0)break;
for (int i = 1; i <= n; i++){
for (int j = 1; j <= n; j++){
cin >> x;
if (x == 'X')
Mark[i][j] = 2;//墙
else
Mark[i][j] = 0;//空
}
}
tempN = maxN = 0;
search(1);
cout << maxN << endl;
}
return 0;
}
void search(int num)
{
int row = num / n+1;
int col = num % n;
if (col == 0) {
col = n;
row--;
}
//行列转换
if (num > n * n){
tempN = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (Mark[i][j] == 1)tempN++;
}
}
if (tempN > maxN){
maxN = tempN;
}
}
else{
if (canplace(row,col)){
Mark[row][col] = 1;
search(num + 1);
Mark[row][col] = 0;
}
search(num + 1);
}
}
bool canplace(int i, int j)
{
int k1, k2;
if (Mark[i][j] == 2)return false;//墙
for (k2 = j - 1; k2 >= 0; k2--) {//判断该点左路
if (Mark[i][k2] == 2)break;
if (Mark[i][k2] == 1)return false;
}
for (k2 = j + 1; k2 <= n; k2++) {//判断该点右路
if (Mark[i][k2] == 2)break;
if (Mark[i][k2] == 1)return false;
}
for (k1 = i - 1; k1 >= 0; k1--) {//判断该点上路
if (Mark[k1][j] == 2)break;
if (Mark[k1][j] == 1)return false;
}
for (k1 = i + 1; k1 <= n; k1++) {//判断该点下路
if (Mark[k1][j] == 2)break;
if (Mark[k1][j] == 1)return false;
}
return true;
}