Chessboard
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 14787 | Accepted: 4607 |
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.
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.
Source
POJ Monthly,charlescpp
题目意思:
一个n*m的棋盘,现用1*2的木板覆盖棋盘,其中有黑色圆的棋盘单位不能被覆盖。问能否把棋盘中可以覆盖的单位全部覆盖(不能重复覆盖)。
思路:
相邻棋盘单位奇偶性不同建图,判断最大匹配*2是否等于可以覆盖点数即可。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <vector> 6 #include <queue> 7 #include <cmath> 8 #include <set> 9 using namespace std; 10 11 #define N 35 12 13 int max(int x,int y){return x>y?x:y;} 14 int min(int x,int y){return x<y?x:y;} 15 int abs(int x,int y){return x<0?-x:x;} 16 17 int n, m; 18 vector<int>ve[N*N]; 19 int from[N*N]; 20 bool visited[N*N]; 21 22 23 int march(int u){ 24 int i, v; 25 for(i=0;i<ve[u].size();i++){ 26 v=ve[u][i]; 27 if(!visited[v]){ 28 visited[v]=true; 29 if(from[v]==-1||march(from[v])){ 30 from[v]=u; 31 return 1; 32 } 33 } 34 } 35 return 0; 36 } 37 int map[N][N]; 38 main() 39 { 40 int i, j, k; 41 42 int x, y; 43 while(scanf("%d %d %d",&n,&m,&k)==3){ 44 memset(map,-1,sizeof(map)); 45 int maxh=0; 46 for(i=0;i<n;i++){ 47 for(j=0;j<m;j++){ 48 if(j==0){ 49 if(i==0) map[i][j]=0; 50 else { 51 if(m&1) map[i][j]=map[i-1][m-1]+1; 52 else map[i][j]=map[i-1][m-1]+2; 53 } 54 } 55 else map[i][j]=map[i][j-1]+1; 56 maxh=max(maxh,map[i][j]); 57 // printf("%d ",map[i][j]); 58 } 59 //cout<<endl; 60 } 61 for(i=0;i<k;i++){ 62 scanf("%d %d",&x,&y); 63 map[y-1][x-1]=-1; 64 } 65 int nn=0; 66 for(i=0;i<n;i++){ 67 for(j=0;j<m;j++){ 68 if(map[i][j]==-1) nn++; 69 } 70 } 71 72 for(i=0;i<=maxh;i++) ve[i].clear(); 73 for(i=0;i<n;i++){ 74 for(j=0;j<m;j++){ 75 if(map[i][j]!=-1&&(map[i][j]&1)){ 76 if(i>0&&map[i-1][j]!=-1) ve[map[i][j]].push_back(map[i-1][j]); 77 if(i<n-1&&map[i+1][j]!=-1) ve[map[i][j]].push_back(map[i+1][j]); 78 if(j>0&&map[i][j-1]!=-1) ve[map[i][j]].push_back(map[i][j-1]); 79 if(j<m-1&&map[i][j+1]!=-1) ve[map[i][j]].push_back(map[i][j+1]); 80 } 81 } 82 } 83 int num=0; 84 memset(from,-1,sizeof(from)); 85 for(i=0;i<=maxh;i++){ 86 memset(visited,false,sizeof(visited)); 87 if((i&1)&&march(i)) num++; 88 } 89 if(num*2==n*m-nn) printf("YES "); 90 else printf("NO "); 91 } 92 }