Time Limit: 2000MS |
|
Memory Limit: 65536K |
Total Submissions: 8985 |
|
Accepted: 2740 |
Description
Alice and Bob often play games on chessboard. One day, Alice draws a board with size M * N. She wants Bob to use a lot of cards with size 1 * 2 to cover the board. However, she thinks it too easy to bob, so she makes some holes on the board (as shown in the figure below).

We call a grid, which doesn’t contain a hole, a normal grid. Bob has to follow the rules below:
1. Any normal grid should be covered with exactly one card.
2. One card should cover exactly 2 normal adjacent grids.
Some examples are given in the figures below:
A VALID solution.
An invalid solution, because the hole of red color is covered with a card.
An invalid solution, because there exists a grid, which is not covered.Your task is to help Bob to decide whether or not the chessboard can be covered according to the rules above.
Input
There are 3 integers in the first line: m, n, k (0 < m, n <= 32, 0 <= K < m * n), the number of rows, column and holes. In the next k lines, there is a pair of integers (x, y) in each line, which represents a hole in the y-th row, the x-th column.
Output
If the board can be covered, output "YES". Otherwise, output "NO".
Sample Input
4 3 2
2 1
3 3
Sample Output
YES
Hint
A possible solution for the sample input

参考程序
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 35;
const int dx[] = {-1, 1, 0, 0},
dy[] = { 0, 0,-1, 1};
int m,n,k,oddn,even,match[N*N/2],number[N][N];
int adj[N*N/2][5];
bool used[N*N],ishole[N][N];
bool init(){
memset(match,0,sizeof(match));
memset(used,0,sizeof(used));
memset(ishole,0,sizeof(ishole));
memset(adj,0,sizeof(adj));
cin>>m>>n>>k;
if ((m*n-k)%2) return false;
for (int i=0,x,y;i<k;i++){
cin>>y>>x;
ishole[x][y]=true;
}
oddn=even=0;
for (int i=1;i<=m;i++)
for (int j=1;j<=n;j++){
if (ishole[i][j]) continue;
if ((i+j)%2)
number[i][j] = ++oddn;
else number[i][j] = ++even;
}
int x1,y1;
for (int x=1;x<=m;x++)
for (int y=1;y<=n;y++)
if (!ishole[x][y] && (x+y)%2){
for (int i=0;i<4;i++){
x1 = x+dx[i];
y1 = y+dy[i];
if (x1<1 || x1>m || y1<1 || y1>n) continue;
if (ishole[x1][y1]) continue;
adj[number[x][y]][++adj[number[x][y]][0]]=number[x1][y1];
}
}
if (oddn!=even) return false;
return true;
}
bool can(int k){
for (int i=1;i<=adj[k][0];i++){
int j=adj[k][i];
if (!used[j])
{
used[j]=true;
if (!match[j]||can(match[j]))
{
match[j]=k;
return true;
}
}
}
return false;
}
bool covered(){
int matchn=0;
for (int i=1;i<=oddn;i++){
if (can(i))
matchn++;
memset(used,0,sizeof(used));
}
if (matchn*2==m*n-k) return true;
else return false;
}
int main(){
if (init())
if (covered()) cout<<"YES\n";
else cout<<"NO\n";
else cout<<"NO\n";
}.
posted on 2011-10-26 17:06
龙在江湖 阅读(190)
评论(0) 编辑 收藏 引用 所属分类:
图论 、
竞赛题解_POJ