Codevs1022:覆盖

来源:互联网 发布:农产品网络销售数据库 编辑:程序博客网 时间:2024/05/30 04:32

1022 覆盖

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 大师 Master

题目描述 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



题解 : 二分图匹配 将每一个池塘标记出来 , 然后 对陆地做二分图匹配,如下图  能看得懂把 然后多判断几个做

一下二分图匹配就ok了。


献上代码:

#include <cstdio>#include <cstring>bool wat[101][101],map[101][101],use[101][101];int n,m,k,ans,px,py;int from[101][101][2],t[5]={0,1,-1,0,0},tt[5]={0,0,0,1,-1};bool find(int x,int y){    for(int i=1;i<=4;i++)//向四周搜索可行的增广路    {        px=x+t[i];py=y+tt[i];        if(px<=0||px>n||py<=0||py>m||wat[px][py])continue;        if (!wat[px][py] && !use[px][py]&& !map[px][py])//排除水塘        {            use[px][py]=true;            if((!from[px][py][0])||(find(from[px][py][0],from[px][py][1])))            {                from[px][py][0]=x;                from[px][py][1]=y;                return true;            }         }    }    return false;}int main(){    scanf("%d%d%d",&n,&m,&k);    int x,y;    for(int i=1;i<=k;i++)    {        scanf("%d%d",&x,&y);        wat[x][y]=true;    }    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)            if((i % 2 && j % 2) || (i%2==0 && j%2==0))map[i][j]=1;//选出红色的1    for(int i=1;i<=n;i++)    {        for(int j=1;j<=m;j++)        {            if(!wat[i][j]&&map[i][j])            {                memset(use, 0, sizeof(use));                if(find(i,j))ans++;            }        }    }    printf("%d",ans);    return 0;}


原创粉丝点击