题目链接: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 "); 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 "); 45 else printf("NO "); 46 } 47 return 0; 48 }