zoukankan      html  css  js  c++  java
  • GHOJ 711 多米诺骨牌

    题目描述

            一个矩形可以划分成M×N个小正方形,其中有一些小正方形不能使用。一个多米诺骨牌占用两个相邻的小正方形。试问整个区域内最多可以不重叠地放多少个多米诺骨牌且不占用任何一个被标记为无法使用的小正方形。

    输入格式

            第一行,两个用空格隔开的正整数M和N。

            第二行,一个正整数K,表示共有K个小正方形不能使用。输入数据保证K<=M×N。

            以下K行每行有两个用空格隔开的数X和Y,表示第X行的第Y个小正方形不能使用。

    输出格式

            一行,为最多能放多少个多米诺骨牌。

     

    输入样例

    3 3

    2

    1 1

    2 2

    输出样例

    3

     

    数据规模

            对于30%的数据,M=1;

            对于50%的数据,M≤2;

            对于70%的数据,M≤3;

            对于100%的数据,M≤50,N≤50。

    题解

            我们设一个点的位置为$(i,  j)$,则根据$i$与$j$的奇偶性是否相同可以将整张图分为两个子图,即二分图。

            那么直接套二分图匹配即可。数据很小,匈牙利就能过。

    #include <iostream>
    #include <cstring> 
    
    #define MAX_M (50 + 5) 
    #define MAX_N (50 + 5)
    
    using namespace std;
    
    int m, n;
    bool b[MAX_M][MAX_N]; 
    const int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};
    bool vis[MAX_M][MAX_N];
    int lx[MAX_M][MAX_N], ly[MAX_M][MAX_N];
    int ans;
    
    bool DFS(int ux, int uy)
    {
        if(b[ux][uy]) return false;
        int vx, vy;
        for(register int i = 0; i < 4; ++i)
        {
            vx = ux + dx[i];
            vy = uy + dy[i];
            if(b[vx][vy] || vis[vx][vy]) continue;
            vis[vx][vy] = true;
            if(!lx[vx][vy] && !ly[vx][vy] || DFS(lx[vx][vy], ly[vx][vy]))
            {
                lx[vx][vy] = ux;
                ly[vx][vy] = uy;
                return true; 
            }
        }
        return false;
    }
    
    int main()
    {
        int tmp;
        cin >> m >> n >> tmp;
        int x, y;
        while(tmp--)
        {
            cin >> x >> y;
            b[x][y] = true;
        }
        for(register int i = 1; i <= m; ++i)
        {
            b[i][0] = b[i][n + 1] = true;
        }
        for(register int i = 1; i <= n; ++i)
        {
            b[0][i] = b[m + 1][i] = true;
        }
        for(register int i = 1; i <= m; ++i)
        {
            for(register int j = (i & 1 ? 1 : 2); j <= n; j += 2)
            {
                memset(vis, 0, sizeof vis);
                if(DFS(i, j)) ++ans;
            }
        }
        cout << ans;
        return 0;
    }
    参考程序
  • 相关阅读:
    编写一个函数func(),将此函数的输入参数(int型)逆序输出显示,如54321 –> 12345,要求使用递归,并且函数体代码不超过8行
    java中两种单例模式
    springMVC配置freemarker 二(问题讨论篇)
    springMVC配置freemarker
    java中@value的环境配置
    java环境log4j日志环境的配置。
    websocket协议
    http报文和浏览器缓存机制
    详解网络连接
    编码总结
  • 原文地址:https://www.cnblogs.com/kcn999/p/11176653.html
Copyright © 2011-2022 走看看