题目大意:
在图中建造炮塔,在互相不能对轰的情况下,最多建造多少个炮塔
题解:
二进制枚举所有点的情况,每个点装炮塔和不装炮塔,检查时从左上角的点到右下角的点,每遇到炮塔就检查这个炮塔右边一行和下方一列
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int n;
bool m[10][10];
bool v[10][10];
int fun(int x){//二进制枚举
int k=1;
int sum=0;
int xx,y;
while(x){
if(x&1){
xx=k/n+1;
if(k%n==0)xx--;
y=k%n;
if(y==0)y=n;
if(!m[xx][y]){
sum++;
v[xx][y]=1;
}
}
k++;
x>>=1;
}
return sum;
}
bool check(){//判断是否符合条件
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(v[i][j]){
for(int k=j+1;k<=n;k++){
if(m[i][k])break;
if(v[i][k])return false;
}
for(int k=i+1;k<=n;k++){
if(m[k][j])break;
if(v[k][j])return false;
}
}
}
return true;
}
int main(){
int ans=0;
while(~scanf("%d",&n)){
if(n==0)break;
ans=0;
memset(m,0,sizeof(m));
char c;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cin>>c;
if(c=='X')m[i][j]=1;
}
for(int i=0;i<(1<<n*n);i++){
memset(v,0,sizeof(v));
int sum=fun(i);
if(check())ans=max(ans,sum);
}
cout<<ans<<endl;
}
return 0;
}