首页 > 代码库 > POJ2446

POJ2446

题目链接:http://poj.org/problem?id=2446

题目大意:

  给一个m*n的方格阵,阵中有 k 个洞,在阵中放入 1*2 规格的小矩形片,洞上不能放矩形片,问能不能用矩形片把所有非洞的方块填满。(说的不太好。。。)

解题思路:

  思路很明确,把方格阵上除了洞之外的小方块分成两种:横纵坐标之和为奇数、横纵坐标之和为偶数,然后求出横纵坐标之和为奇(偶)数的最大匹配数 M ,如果 M == (m*n-k)/2,输出 YES,否则输出 NO。里面有几个坑,我在代码中标注出来了。

AC代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 const int cx[4]={0,0,1,-1}, cy[4]={1,-1,0,0};
 6 bool hole[200][200],vis[200][200];
 7 int to[200][200],m,n;
 8 bool finds(int x,int y){
 9     for(int i=0;i<4;i++){
10         int dx=x+cx[i],dy=y+cy[i];
11         if(dx>0&&dx<=m&&dy>0&&dy<=n&&!vis[dx][dy]&&!hole[dx][dy]){
12             vis[dx][dy]=true;
13             if(to[dx][dy]==0||finds((to[dx][dy]-1)/n+1,(to[dx][dy]-1)%n+1)){//这里要注意finds()函数中的参数,一开始表示错误,WA了几发。
14                 to[dx][dy]=(x-1)*n+y;
15                 return true;
16             }
17         }
18     }
19     return false;
20 }
21 int main(){
22     int k,x,y;
23     while(scanf("%d%d%d",&m,&n,&k)==3){
24         memset(hole,false,sizeof(hole));
25         memset(to,0,sizeof(to));
26         for(int i=0;i<k;i++){
27             scanf("%d%d",&x,&y);//注意,x是列,y才是行,大坑。
28             hole[y][x]=true;
29         }
30         if((m*n-k)%2!=0){
31             printf("NO\n");
32             continue;
33         }
34         int ok=0;
35         int ji=0;
36         for(int i=1;i<=m;i++){
37             for(int j=1;j<=n;j++){
38                 if((i+j)%2==1||hole[i][j])  continue;
39                 memset(vis,false,sizeof(vis));
40                 if(finds(i,j))
41                     ok++;
42             }
43         }
44         if(ok==(m*n-k)/2)  printf("YES\n");
45         else    printf("NO\n");
46     }
47     return 0;
48 }

 

POJ2446