分析
因为观察到不能重叠覆盖,然后四相邻的两个格子具有一个不同的特征(一个是 i + j = 奇 i+j=奇 i+j=奇,一个是 i + j = 偶 i+j=偶 i+j=偶),所以又是一个二分图的模型,其中一个棋子能放上去相当于一组匹配,可见题目就是要判断是否有完美匹配。匈牙利就行。
上代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int m,n,k,a[50][50],g[1100][1100],tot,ans;
int cover[1100],link[1100];
bool find(int x)
{
for(int i=1;i<=tot;i++)
{
if(g[x][i]&&!cover[i])
{
cover[i]=1;
int p=link[i];
link[i]=x;
if(p==0||find(p))
{
return true;
}
link[i]=p;
}
}
return false;
}
int main()
{
cin>>m>>n>>k;
for(int i=1;i<=k;i++)
{
int x,y;
cin>>x>>y;
a[x][y]=-1;
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i][j]!=-1) a[i][j]=++tot;
}
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i][j]==-1||(i+j)%2!=0) continue;
if(a[i][j+1]!=-1&&j+1<=n) g[a[i][j]][a[i][j+1]]=1;
if(a[i][j-1]!=-1&&j-1>=1) g[a[i][j]][a[i][j-1]]=1;
if(a[i+1][j]!=-1&&i+1<=m) g[a[i][j]][a[i+1][j]]=1;
if(a[i-1][j]!=-1&&i-1>=1) g[a[i][j]][a[i-1][j]]=1;
}
}
for(int i=1;i<=tot;i++)
{
for(int j=1;j<=tot;j++)
{
cout<<g[i][j]<<' ';
}
cout<<endl;
}
for(int i=1;i<=tot;i++)
{
memset(cover,0,sizeof(cover));
if(find(i)) ans++;
}
if(ans*2==n*m-k) cout<<"YES";
else cout<<"NO";
return 0;
}
但这其实不是AC代码(虽然我觉得一点问题没有)
想要AC还要所谓黑白染色,然后判断匹配数=黑色数量,但事实上这是完全不对的!!
我用所谓的AC代码测如下数据居然输出YES。。
2 2 1
2 2
那就附上假AC代码吧:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int m,n,k,a[50][50],g[1100][1100],tot=0,ans=0,b=0;
int cover[1100],link[1100];
bool find(int x)
{
for(int i=1;i<=tot;i++)
{
if(g[x][i]==1&&!cover[i])
{
cover[i]=1;
int p=link[i];
link[i]=x;
if(p==0||find(p))
{
return true;
}
link[i]=p;
}
}
return false;
}
int main()
{
cin>>m>>n>>k;
for(int i=1;i<=k;i++)
{
int x,y;
cin>>x>>y;
a[x][y]=-1;
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i][j]!=-1)
{
a[i][j]=++tot;
if((i+j)%2==0)
{
b++;
}
}
}
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i][j]==-1||(i+j)%2!=0) continue;
if(a[i][j+1]!=-1&&j+1<=n) g[a[i][j]][a[i][j+1]]=1;
if(a[i][j-1]!=-1&&j-1>=1) g[a[i][j]][a[i][j-1]]=1;
if(a[i+1][j]!=-1&&i+1<=m) g[a[i][j]][a[i+1][j]]=1;
if(a[i-1][j]!=-1&&i-1>=1) g[a[i][j]][a[i-1][j]]=1;
}
}
for(int i=1;i<=tot;i++)
{
memset(cover,0,sizeof(cover));
if(find(i)) ans++;
}
if(ans==b) cout<<"YES";
else cout<<"NO";
return 0;
}