zoukankan      html  css  js  c++  java
  • Code[VS] 1022 覆盖 题解

    Code[VS] 1022 覆盖 题解


    题目传送门:Code[VS] 1022
    题目描述 Description

    有一个N×M的单位方格中,其中有些方格是水塘,其他方格是陆地。如果要用1×2的矩阵区覆盖(覆盖过程不容许有任何部分重叠)这个陆地,那么最多可以覆盖多少陆地面积。

    输入描述 Input Description

    输入文件的第一行是两个整数NM  (1<=NM<=100),第二行为一个整数K( K<=50),接下来的K行,每行两个整数X,Y表示K个水塘的行列位置。(1<=X<=N1<=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

    ____________________________________分割线_____________________________________

    分析:

    将矩形的每一块分为 0 , 1 两个集合,相邻的两块属于不同的集合,如下图:

    这时,这个问题就转化为一个典型的二分图匹配,可以使用Hungary Algorithm 解决。

     

    代码:

     1 #include "cstdio"
     2 #include "cstring"
     3 #include "algorithm"
     4 
     5 using namespace std ;
     6 const int maxN = 210 ;
     7 const int INF = 2147483647 ; 
     8 
     9 bool wat[ maxN ][ maxN ] , map[ maxN ][ maxN ] , used[ maxN ][ maxN ] ;
    10 
    11 int N , M , k , ans , px , py ;
    12 
    13 int from[ maxN ][ maxN ][ 2 ] ;
    14 
    15 int _1[ 5 ] = { 0 , 1 , -1 , 0 , 0 } , _2[ 5 ] = { 0 , 0 , 0 , 1 , -1 } ;//方向 
    16 
    17 bool find ( int x , int y ) 
    18 {
    19     int px , py ;
    20     for(int i=1 ; i<=4 ; ++i )
    21     {
    22         px = x + _1[i] ,py = y + _2[i];
    23         if( px<=0 || px>N || py<=0 || py>M || wat[ px ][ py ] ) continue ;
    24         if ( !wat[ px ][ py ] && !used[ px ][ py ] && !map[ px ][ py ])
    25         {
    26             used[ px ][ py ] = true ;
    27             if( ( !from[ px ][ py ][ 0 ] ) || (find( from[ px ][ py ][ 0 ] , from[ px ][ py ][ 1 ] ) ) ) 
    28             {
    29                 from[ px ][ py ][ 0 ] = x ;
    30                 from[ px ][ py ][ 1 ] = y ;
    31                 return true ;
    32             } 
    33         }
    34     }
    35     return false ;
    36 }
    37 int main()
    38 {
    39     scanf( "%d%d%d" , &N , &M , &k ) ;
    40     for(int i=1 ; i<=k ; ++i )
    41     {
    42         int _x , _y ;
    43         scanf( "%d%d" , &_x , &_y ) ;
    44         wat[ _x ][ _y ] = true ;
    45     }
    46     for(int i=1 ; i<=N ; ++i )
    47         for(int j=1 ; j<=M ; ++j )
    48             if((i % 2 && j % 2) || (i%2==0 && j%2==0))map[ i][ j ] = 1 ;
    49     for(int i=1 ; i<=N ; ++i )
    50     {
    51         for(int j=1 ; j<=M ; ++j )
    52         {
    53             if( !wat[ i ][ j ] && map[ i ][ j ] )
    54             {
    55                 memset ( used, 0 , sizeof ( used ) ) ;
    56                 if ( find ( i , j ) ) ans++ ;
    57             }
    58         }
    59     }
    60     printf( "%d" , ans ) ;
    61     return 0 ;
    62 }

    2016-09-16 15:46:24

     

    (完)

  • 相关阅读:
    八. 输入输出(IO)操作2.面向字符的输入流
    八. 输入输出(IO)操作1.输入输出基本概念
    七. 多线程编程11.线程的挂起、恢复和终止
    七. 多线程编程10.线程死锁
    nginx 配置身份验证 http_auth_basic_module
    liunx mysql 备份
    8080 端口只允许内网访问配置
    nginx 配置白名单
    liunx tomcat 运行模式apr
    liunx contos 7.4 安装redis集群
  • 原文地址:https://www.cnblogs.com/shadowland/p/5876554.html
Copyright © 2011-2022 走看看