题目意思是给你一个n*m大的棋盘,用中国象棋的规则来摆炮,给t个表示棋盘上有的棋子的坐标,问你剩下的空位中,在保存每个炮都不会被互吃的情况下能摆多少炮(就是每两个炮中间要么没有棋,要么棋的总数大于一)
算是《HDU2553N皇后问题》的升级版。`
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAXN=100;
int map[MAXN][MAXN];
int n,m;
int t,ans,sum,flag;
void dfs(int x,int y,int cnt)
{
ans=max(ans,cnt);//取最大记录
map[x][y]=2;//标记当前位置放了一个炮
for(int j=y+1;j<m;j++)//查看当前位置的右边能不能放棋
{
if(map[x][j]==1) continue;
flag=1;//判断能不能放
sum=0;//用来计数
for(int k=j-1;k>=0;k--)//查看当前位置的左边是不是有炮能攻击现在的位置
{
if(map[x][k])//只要不算0,都算炮架
sum++;
if(sum==2&&map[x][k]==2)//说明有炮能攻击当前位置
{
flag=0;
break;
}
}
if(flag)//如果左边没有
{
sum=0;
for(int i=x-1;i>=0;i--)//判断上面有没有
{
if(map[i][j])
sum++;
if(sum==2&&map[i][j]==2)
{
flag=0;
break;
}
}
if(flag)//都没有就标记当前位置继续搜索
{
map[x][j]=2;
dfs(x,j,cnt+1);
map[x][j]=0;
}
}
}
for(int i=x+1;i<n;i++)//当前的行已经摆完,换下一行
{
for(int j=0;j<m;j++)//下面部分同上
{
if(map[i][j]==1)
continue;
sum=0;
flag=1;
for(int t=i-1;t>=0;t--)
{
if(map[t][j])
sum++;
if(sum==2&&map[t][j]==2)
{
flag=0;
break;
}
}
if(flag)
{
map[i][j]=2;
dfs(i,j,cnt+1);
map[i][j]=0;
}
}
}
}
int main()
{
while(cin>>n>>m>>t)
{
memset(map,0,sizeof(map));//没有棋子的地方就全部用0表示
int x,y;
while(t--)
{
cin>>x>>y;
map[x][y]=1;//其他棋子用1表示
}
ans=0;//记录最大的摆放个数
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(map[i][j]==0)
{
map[i][j]=2;//2表示炮
dfs(i,j,1);//摆放了一个炮,开始深搜。
map[i][j]=0;//回溯
}
cout<<ans<<endl;
}
return 0;
}