http://acm.hdu.edu.cn/showproblem.php?pid=1045
在最多为 4 * 4 的方阵中,圆形代表堡垒,正方形代表墙,堡垒射出的子弹无法穿过墙,求任何两个堡垒都不能射中对方的最大的堡垒放置数?
#pragma warning (disable:4786)
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
string map[6];
int arr[20]; //总元素数组
int used_row[6],used_column[6]; //标记行和列是否已被使用
int n; //行(列)数
int DFS( int index ){
if( index == n * n )
return 0;
//根据元素的坐标计算其所在行列数
int row = index / n;
int column = index % n;
//如果是墙,将其所在的行和列设置为未使用
if( arr[ index ] == 1 ){
used_row[row] = 0;
used_column[column] = 0;
return DFS( index + 1 );
}
//对两种情况进行回溯,一种是在该处放置堡垒,另一种是不放置
int re1 = DFS( index + 1 );
int re2 = 0;
if( used_row[row] == 0 && used_column[column] == 0 ){
used_row[row] = 1;
used_column[column] = 1;
re2 = DFS( index +1 ) + 1;
//不要忘了恢复状态
used_row[row] = 0;
used_column[column] = 0;
}
//返回放置和不放置堡垒两种情况中得到较好结果的那种
if( re2 < re1 )
return re1;
else return re2;
}
int main(){
int i,j;
while( scanf( "%d", &n ) && n ){
memset( used_row, 0, sizeof( used_row ) );
memset( used_column, 0, sizeof( used_column ) );
memset( arr, 0, sizeof(arr) );
string s;
for( i = 0; i < n; i ++ ){
cin>>map[i];
for( j = 0; j < n; j ++ ){
if( map[i][j] == 'X' )
arr[i * n + j] = 1;
}
}
printf( "%d\n", DFS( 0 ) );
}
}