• [Usaco2005 Jan]Muddy Fields泥泞的牧场


    Description

    雨连续不断的击打了放牛的牧场,一个R行C列的格子(1 <= R <= 50,
    1 <= C <= 50)。虽然这对草来说是件好事,但这却使得一些没有草遮盖的土地
    变得很泥泞。牛们是很小心的食草动物;他们不想在吃草时把蹄子弄脏。
    为了避免它们把蹄子弄脏,农夫约翰要在那些泥泞的地方铺上木板子。每个1个
    单位宽,长度任意。每个板子都必须放到与牧场一边平行。
    农夫约翰希望用最少的板子来覆盖泥泞的部分。一些地方可能需要多于一块板
    子来覆盖。木板不可以遮住草地,剥夺牛吃草的地方,但是他们可以相互重叠。
    计算最少需要多少块板子来覆盖所有的泥地。

    Input

    * 第一行:两个整数R和C,由空格隔开。
    * 第2到第R+1行:每行为一个长度为C的字符串。'*'代表泥地,'.'代表草地。
    无空格。

    Output

    * 第一行:一个整数,其值为最少需要的板子数目

    Sample Input

    4 4
    *.*.
    .***
    ***.
    ..*.

    Sample Output

    4
    输出细节:
    板子 1, 2, 3 和 4 是这样摆放的:
    1.2.
    .333
    444.
    ..2.
    板子2与3,4重叠。
    
    

    思路

    这题因为板子可以连续盖,并且可以相互重叠,
    所以我们可以将可以连续盖的板子打上编号
    如样例:
    行编号:
    1 0 2 0
    0 3 3 3
    4 4 4 0
    0 0 5 0
    列编号:
    1 0 2 0
    0 3 2 4
    5 3 2 0
    0 0 2 0
    这样每一个点就有了可以覆盖的板子选择
    如:
    (1,1)可以选择横着编号为1的板子,或竖着编号为1的板子//这两个好像没啥区别
    (3,4)可以选择横着编号为5的板子,或竖着编号为2的板子

    然后将每一个可以覆盖的点,与他可以选择的板子连边,
    这样题目就转换成了最小点覆盖集;

    代码
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    inline ll read()
    {
        ll a=0,f=1; char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
        while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
        return a*f;
    }
    ll s,n,m,num;
    ll aa[10001],f[10001],head[20001];
    ll map1[101][101],map2[101][101],map3[101][101];
    struct suffix
    {
        ll to,stb;
    }a[20001];
    inline void insert(ll x,ll y)//前向星储存
    {
        s++;
        a[s].to=y;
        a[s].stb=head[x];
        head[x]=s;
    }
    inline ll dfs(ll x)
    {
        for(ll i=head[x];i;i=a[i].stb)
        {
            ll xx=a[i].to;
            if(f[xx]==num)
                continue;
            f[xx]=num;
            if(!aa[xx]||dfs(aa[xx]))
            {
                aa[xx]=x;
                return true;
            }
        }
        return false;
    }
    inline ll findout()
    {
        ll sum=0;num=0;
        for(ll i=1;i<=n*m;i++)
        {
            num++;//一点点优化,不需要memset了
            if(dfs(i))
                sum++;
        }
        return sum;
    }
    int main()
    {
        n=read();m=read();
        for(ll i=1;i<=n;i++)
        for(ll j=1;j<=m;j++)
        {
            char x;
            cin>>x;
            if(x=='*')
                map1[i][j]=1;
            else if(x=='.')
                map1[i][j]=0;
        }
        ll t=0,tt=0;
        for(ll i=1;i<=n;i++)
        for(ll j=1;j<=m;j++)//计算每个板子的编号
        {
            if(map1[i][j])
            {
                if(j>1&&map1[i][j-1])
                    map2[i][j]=map2[i][j-1];
                else
                    map2[i][j]=++t;
                if(i>1&&map1[i-1][j])
                    map3[i][j]=map3[i-1][j];
                else
                    map3[i][j]=++tt;
            }
        }
        /*for(ll i=1;i<=n;i++){
        for(ll j=1;j<=m;j++)
            cout<<map2[i][j];
        cout<<endl;}*/
        for(ll i=1;i<=n;i++)
        for(ll j=1;j<=m;j++)
        if(map1[i][j])
            insert(map2[i][j],map3[i][j]); 
        ll ans=findout();
        printf("%lld",ans);
        return 0;
    }
     
     
    
    
  • 相关阅读:
    js事件委托篇(附js一般写法和js、jq事件委托写法)
    markdown工作随笔总结
    论实际开发中按钮显示和隐藏自身或其他元素
    彻底理解行内元素和块级元素,不必硬背
    redis搭建主从配置
    [Python图像处理]三.获取图像属性及通道处理
    [Python图像处理]二 OpenCV借助Numpy库读取和修改像素
    [Python图像处理]一.图像处理基础知识及OpenCV入门函数
    opencv2图像处理--灰度变换
    提取新闻网站信息
  • 原文地址:https://www.cnblogs.com/wzx-RS-STHN/p/12901983.html
Copyright © 2020-2023  润新知