数组ans用于记录已安装摄像头的点
#include <iostream>
#include <string.h>
#include <string>
#include <stdio.h>
using namespace std;
int ma[20],ans[20],maxn;
int n;
//函数声明
bool is_catch(int x,int y);
void read();
void dp(int cou);
//函数定义
void read()
{
while(cin>>n)
{
memset(ans,0,sizeof(ans));
memset(ma,0,sizeof(ma));
for(int i=0;i<20;i++)
{
ma[i]=0;
ans[i]=0;
}
maxn=0;
char cc;
for(int i=1;i<=n*n;i++)
{
cin>>cc;
if(cc=='X')
ma[i]=2;//2代表障碍物
}
dp(0);
cout<<maxn<<endl;
}
return;
}
void dp(int cou)
{
int i,j;
for(i=1;i<=n*n;i++)//检查每个点是否能被摄像头抓取到
{
if(ma[i]==2)
continue;
for(j=0;j<cou;j++)
if(is_catch(ans[j],i)) break;
if(j==cou)//此点未被摄像头抓取到
break;
}
if(i==(n*n+1))//所有点都被抓取到,则为一组解
{
if(maxn<cou)
maxn=cou;
return;
}
for(i=1;i<=n*n;i++)
{
if(ma[i]==2)
continue;
for(j=0;j<cou;j++)
{
if(is_catch(ans[j],i))
break;
}
if(j==cou)//该位置可以放置摄像头
{
ans[cou]=i;
dp(cou+1);
}
}
}
//判断当前摄像头是否可拍摄到此点
bool is_catch(int x,int y)//x为摄像头,y为需要判断的点
{
if(x==y)
return true;
bool flag=false;
int hang=(x-1)/n+1;
for(int i=x-1;i>0;i--)//同行左面
{
if((i-1)/n+1 != hang || ma[i]==2)
break;
if(i==y)
{
flag=true;
break;
}
}
if(flag)
return true;
for(int i=x+1;i<=17;i++)//同行右面
{
if((i-1)/n+1 != hang || ma[i]==2)
break;
if(i==y)
{
flag=true;
break;
}
}
if(flag)
return true;
for(int i=x-n;i>0;i=i-n)//同列上面
{
if(ma[i]==2)
break;
if(i==y)
{
flag=true;
break;
}
}
if(flag)
return true;
for(int i=x+n;i<=n*n;i=i+n)//同列下面
{
if(ma[i]==2)
break;
if(i==y)
{
flag=true;
break;
}
}
return flag;
}
int main()
{
read();
return 0;
}
http://icpc.njust.edu.cn/Problem/Local/1014/