题目描述 Description
有一个N×M的单位方格中,其中有些方格是水塘,其他方格是陆地。如果要用1×2的矩阵区覆盖(覆盖过程不容许有任何部分重叠)这个陆地,那么最多可以覆盖多少陆地面积。
输入描述 Input Description
输入文件的第一行是两个整数N,M (1<=N,M<=100),第二行为一个整数K( K<=50),接下来的K行,每行两个整数X,Y表示K个水塘的行列位置。(1<=X<=N,1<=Y<=M)。
输出描述 Output Description
输出所覆盖的最大面积块(1×2面积算一块)。
样例输入 Sample Input
4 4
6
1 1
1 4
2 2
4 1
4 2
4 4
样例输出 Sample Output
4
这道题目中的一个矩阵会覆盖2块陆地,所以我们可以通过为陆地编号的方式将陆地分为两组,相邻的两块陆地间有一条边相连,即可进行二分图最大匹配的查找,注意需要排除水塘。
献上代码
1 #include <cstdio> 2 #include <cstring> 3 bool wat[101][101],map[101][101],use[101][101]; 4 int n,m,k,ans,px,py; 5 int from[101][101][2],t[5]={0,1,-1,0,0},tt[5]={0,0,0,1,-1}; 6 bool find(int x,int y) 7 { 8 for(int i=1;i<=4;i++)//向四周搜索可行的增广路 9 { 10 px=x+t[i];py=y+tt[i]; 11 if(px<=0||px>n||py<=0||py>m||wat[px][py])continue; 12 if (!wat[px][py] && !use[px][py]&& !map[px][py])//排除水塘 13 { 14 use[px][py]=true; 15 if((!from[px][py][0])||(find(from[px][py][0],from[px][py][1]))) 16 { 17 from[px][py][0]=x; 18 from[px][py][1]=y; 19 return true; 20 } 21 } 22 } 23 return false; 24 } 25 int main() 26 { 27 scanf("%d%d%d",&n,&m,&k); 28 int x,y; 29 for(int i=1;i<=k;i++) 30 { 31 scanf("%d%d",&x,&y); 32 wat[x][y]=true; 33 } 34 for(int i=1;i<=n;i++) 35 for(int j=1;j<=m;j++) 36 if((i % 2 && j % 2) || (i%2==0 && j%2==0))map[i][j]=1;//选出红色的1 37 for(int i=1;i<=n;i++) 38 { 39 for(int j=1;j<=m;j++) 40 { 41 if(!wat[i][j]&&map[i][j]) 42 { 43 memset(use, 0, sizeof(use)); 44 if(find(i,j))ans++; 45 } 46 } 47 } 48 printf("%d",ans); 49 return 0; 50 }
时间: 2024-10-29 19:12:10