题意很简单,就是问你能不能用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; }