蒜头君喜欢下棋。最近它迷上了国际象棋。国际象棋的棋盘可以被当做一个 8\times 88×8 的矩阵,棋子被放在格子里面(不是和中国象棋一样放在线上)。
蒜头君特别喜欢国际象棋里面的马,马的移动规则是这样的:横着走两步之后竖着走一步,或者横着走一步之后竖着走两步。例如,一匹马在 (3,3)(3,3) 的位置,则它可以到达的地方有 (1,2)(1,2),(2,1)(2,1),(1,4)(1,4),(4,1)(4,1),(5,2)(5,2),(2,5)(2,5),(5,4)(5,4),(4,5)(4,5) 八个地方。蒜头君想要把整个棋盘都放上马,并且让这些马不能相互攻击(即任何一匹马不能走一步之后就到达另一匹马的位置)。蒜头君当然知道在 8 \times 88×8 的棋盘上怎么放马,但如果棋盘变为 n \times mn×m 的,蒜头君就不懂了。他希望你来帮忙他计算一下究竟能放多少匹马。
输入格式
共一行,两个整数nn和mm(1 \leq n , m \leq 10001≤n,m≤1000),代表棋盘一共有 nn行 mm 列。
输出格式
输出一个整数,代表棋盘上最多能放的马的数量。
样例输入1
2 4
样例输出1
4
样例输入2
3 4
样例输出2
6
第一次看到这样的dfs...
我们从某一点出发,把这一点当做-1,之后开始dfs,他能到达的点(马子走)都设为1,再从能到达的点再遍历,设为-1.
这样能把这些点分为1和-1.这是相互冲突的。这样之后我们还会可能有一些点没有被遍历到,我们再找那些等于0,也就是
没有被遍历到的,再重复过程。我们的第二轮第三轮...的遍历不用担心出发点是取1,还是-1的问题。因为每一轮都是相互独立的,因为永远也到达不了其他轮的地方。所以依然是从-1开始取即可。
最后我们统计1的个数还有-1的个数,取最大值即可
#include <bits/stdc++.h>
using namespace std;
int mp[1100][1100];
int dir[8][2] = {-2,1, -1,2, 1,2, 2,1, 2,-1, 1,-2, -1,-2, -2,-1};
int n,m;
void dfs(int x,int y)
{
for(int i=0;i<8;i++)
{
int tx=x+dir[i][0];
int ty=y+dir[i][1];
if(tx<1||ty<1||tx>n||ty>m||(mp[tx][ty]!=0))
{
continue;
}
mp[tx][ty]=-mp[x][y];
dfs(tx,ty);
}
}
int main()
{
cin>>n>>m;
memset(mp,0,sizeof(mp));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(mp[i][j]==0)
{
mp[i][j]=-1;
dfs(i,j);
}
}
}
int sum=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(mp[i][j]==1)
{
sum++;
}
}
}
cout<<max(sum,n*m-sum)<<endl;
}