题意很简单,就是问你能不能用1*2的格子覆盖给你的图,其中会有坑。
这个题有点坑人了,一定注意一下它的行和列给出的顺序。
思路:把他抽象成二分图模型,其中i+j为偶数的为一个集合,为奇数的为另一个集合,然后找出二分图最大匹配,判断是否为m+n-k的一半。
下面是代码:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int grid[40][40];
int con[1100][1100];
int pre[1100],vis[1100];
int dx[]= {0,0,1,-1};
int dy[]= {1,-1,0,0};
int n,m,k;
int p,q;
int g,h;
bool dfs(int i)
{
for(int j=1; j<=h; j++)
{
if((!vis[j])&&con[j][i])
{
vis[j]=1;
//cout<<con[i][j];
if(pre[j]==0||dfs(pre[j]))
{
pre[j]=i;
return true;
}
}
}
return false;
}
int main()
{
//freopen("in.txt","r",stdin);
int x,y;
cin>>m>>n>>k;
if((m*n-k)%2)
{
cout<<"NO"<<endl;
}
else
{
memset(grid,0,sizeof(grid));
memset(pre,0,sizeof(pre));
memset(con,0,sizeof(con));
x=y=1;
for(int i=1; i<=m; i++)
for(int j=1; j<=n; j++)
{
if((i+j)%2==0)
grid[i][j]=x++;
else
grid[i][j]=y++;
}
g=x-1;
h=y-1;
//cout<<g<<h;
for(int i=1; i<=k; i++)
{
cin>>x>>y;
grid[y][x]=-1;
}
for(int i=1; i<=m; i++)
for(int j=1; j<=n; j++)
{
if((grid[i][j]!=-1)&&((i+j)%2==0))
{
for(int k=0; k<4; k++)
{
p=i+dx[k];
q=j+dy[k];
if((p>=1)&&(p<=m)&&(q>=1)&&(q<=n)&&(grid[p][q]!=-1))
{
con[grid[i][j]][grid[p][q]]=1;
}
}
}
}
int ans=0;
for(int i=1; i<=g; i++)
{
memset(vis,0,sizeof(vis));
if(dfs(i))
ans++;
}
if(((m*n-k)/2)==ans)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}