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.
Source
POJ Monthly,charlescpp
题目大意:
有那么一个棋盘和很多1*2大小的方块,棋盘上还有一些用坐标表示的洞,求能否不重叠且不覆盖破洞地用方块铺满整
思路:
因为对于每一个单独的点只能和其他四个临近点一起放上一个方块,所以对每个点四周可以一起放置的点连边,然后判断是否能铺满也就是是否完美匹配
优化:
假设有两个相邻点a(x,y),b(s,t),那么a->b和b->a其实是同一种,所以可以想到枚举偶数点然后对临近点连边,大概是少一半的时间。(然而我比较懒而且已经ac了不是吗:-P)
源代码/pas:
type
edge=record
x,y,next:longint;
end;
const
dx:array[1..4]of integer=(-1,1,0,0);
dy:array[1..4]of integer=(0,0,-1,1);
var
link,ls:array[0..1024]of longint;
f:array[0..33,0..33]of longint;
e:array[0..4096]of edge;
v:array[0..1024]of boolean;
maxE,n,m,num:longint;
procedure add(x,y:longint);
begin
inc(maxE);
e[maxE].x:=x;
e[maxE].y:=y;
e[maxE].next:=ls[x];
ls[x]:=maxE;
end;
function find(x:longint):boolean;
var
i,k:longint;
begin
find:=true;
i:=ls[x];
while i>0 do
with e[i] do
begin
if not v[y] then
begin
v[y]:=true;
k:=link[y];
link[y]:=x;
if (k=0)or find(k) then exit;
link[y]:=k;
end;
i:=next;
end;
find:=false;
end;
procedure main;
var
i:longint;
begin
for i:=1 to num do
begin
fillchar(v,sizeof(v),false);
if not find(i) then
begin
writeln('NO');
exit;
end;
end;
writeln('YES');
end;
procedure init;
var
i,j,l,k,x,y:longint;
begin
readln(m,n,k);
for i:=1 to k do
begin
readln(x,y);
f[x,y]:=-1;
end;
for i:=1 to n do
for j:=1 to m do
if f[i,j]=0 then
begin
inc(num);
f[i,j]:=num;
end;
for i:=1 to n do
for j:=1 to m do
if f[i,j]>0 then
for l:=1 to 4 do
if f[i+dx[l],j+dy[l]]>0 then
add(f[i,j],f[i+dx[l],j+dy[l]]);
end;
begin
init;
main;
end.