poj Chessboard 2446 (最大匹配&转换)
2016-03-25 13:45
471 查看
Chessboard
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
Sample Output
Hint
A possible solution for the sample input.
//题意:
给你一个m*n的矩形,现在在这个矩形上有k个洞,告诉你这k个洞的坐标位置,问是否可以用1*2的矩形纸片将除了洞的其他的位置都遮住,并且1*2的小矩形不能有相互遮盖。
//思路:
把这个棋盘看成一个类似国际象棋的棋盘,黑白相间的那种。任何2个相邻的格子肯定是不同颜色的(黑和白)。经过研究发现,如果一个格子的行号和列号加起来为奇数,那与它相邻的格子的行号和列号加起来一定是偶数,如果一个格子的行号和列号加起来为偶数,那与它相邻的格子的行号和列号加起来一定是奇数。
这样,我们就可以把这张棋盘分为奇数集合和偶数集合。加边的时候,我们只需要加它上面或左面就可以了。。
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 15901 | Accepted: 4926 |
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.
//题意:
给你一个m*n的矩形,现在在这个矩形上有k个洞,告诉你这k个洞的坐标位置,问是否可以用1*2的矩形纸片将除了洞的其他的位置都遮住,并且1*2的小矩形不能有相互遮盖。
//思路:
把这个棋盘看成一个类似国际象棋的棋盘,黑白相间的那种。任何2个相邻的格子肯定是不同颜色的(黑和白)。经过研究发现,如果一个格子的行号和列号加起来为奇数,那与它相邻的格子的行号和列号加起来一定是偶数,如果一个格子的行号和列号加起来为偶数,那与它相邻的格子的行号和列号加起来一定是奇数。
这样,我们就可以把这张棋盘分为奇数集合和偶数集合。加边的时候,我们只需要加它上面或左面就可以了。。
#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<iostream> #define INF 0x3f3f3f3f #define IN __int64 #define ull unsigned long long #define ll long long #define N 1100 #define M 1000000007 using namespace std; int head ,next[N*N],key[N*N],top; int y ; int vis ; int map ; int m,n,k; void add(int u,int v) { key[top]=v; next[top]=head[u]; head[u]=top++; } int dfs(int u) { int v; for(int i=head[u];i!=-1;i=next[i]) { v=key[i]; if(!vis[v]) { vis[v]=1; if(y[v]==-1||dfs(y[v])) { y[v]=u; return 1; } } } return 0; } int main() { int xx,yy; while(scanf("%d%d%d",&m,&n,&k)!=EOF) { if((m*n-k)&1) { printf("NO\n"); continue; } top=0; memset(head,-1,sizeof(head)); memset(y,-1,sizeof(y)); memset(map,1,sizeof(map)); for(int i=0;i<k;i++) { scanf("%d%d",&yy,&xx); map[xx-1][yy-1]=0; } for(int i=0;i<m;i++) { for(int j=0;j<n;j++) { if(map[i][j]) { if(i-1>=0&&map[i-1][j])//上下方向连接 { if((i+j)&1)//从下到上 add(i*n+j,(i-1)*n+j); else//从上到下 add((i-1)*n+j,i*n+j); } if(j-1>=0&&map[i][j-1])//左右方向连接 { if((i+j)&1)//从右向左 add(i*n+j,i*n+j-1); else//从左向右 add(i*n+j-1,i*n+j); } } } } int sum=0; for(int i=0;i<n*m;i++) { memset(vis,0,sizeof(vis)); if(dfs(i)) sum++; } printf(sum==((m*n-k)/2)?"YES":"NO"); } return 0; }
相关文章推荐
- sed作业1
- android开发之网络请求框架比较
- fstream的基础用法
- SurfaceView双缓冲测试
- 【UVALive - 3211】Now or later (二分+2-SAT)
- 实验一 命令解释程序的编写
- 189. Rotate Array
- Thrift开发示例
- static_cast和reinterpret_cast
- Android中使用Handler造成内存泄露的分析和解决
- Jenkins快速上手
- Android UI设计规范
- VCC、VDD、VSS
- React Native 环境配置
- 【Java学习-J.160325.0.1】JDK安装与配置环境变量
- 读书笔记(chapter5)
- require JS入门 及 打包
- Thrift简介
- C#获取周一、周日的日期 函数类
- 帝国败局:一代首富,因何退隐江湖?