zoukankan      html  css  js  c++  java
  • P1204 [USACO1.2]挤牛奶Milking Cows

    题目描述

    三个农民每天清晨5点起床,然后去牛棚给3头牛挤奶。第一个农民在300秒(从5点开始计时)给他的牛挤奶,一直到1000秒。第二个农民在700秒开始,在 1200秒结束。第三个农民在1500秒开始2100秒结束。期间最长的至少有一个农民在挤奶的连续时间为900秒(从300秒到1200秒),而最长的无人挤奶的连续时间(从挤奶开始一直到挤奶结束)为300秒(从1200秒到1500秒)。

    你的任务是编一个程序,读入一个有N个农民(1 <= N <= 5000)挤N头牛的工作时间列表,计算以下两点(均以秒为单位):

    最长至少有一人在挤奶的时间段。

    最长的无人挤奶的时间段。(从有人挤奶开始算起)

    输入输出格式

    输入格式:

     

    Line 1:

    一个整数N。

    Lines 2..N+1:

    每行两个小于1000000的非负整数,表示一个农民的开始时刻与结束时刻。

     

    输出格式:

     

    一行,两个整数,即题目所要求的两个答案。

     

    输入输出样例

    输入样例#1:
    3
    300 1000
    700 1200
    1500 2100
    
    输出样例#1:
    900 300
    

    说明

    题目翻译来自NOCOW。

    USACO Training Section 1.2

    题解:前缀和打标记模拟

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n,x,y,l,r,ans_youren,ans_wuren,youren,wuren;
    int sum[1000005];
    int main(){
        scanf("%d",&n);
        l=0x7fffffff;r=-1;
        ans_youren=ans_wuren=-1;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&x,&y);
            l=min(l,x);
            r=max(r,y);
            sum[x]++;sum[y]--;
        }
        for(int i=l;i<=r;i++)sum[i]+=sum[i-1];
        for(int i=l;i<=r;i++){
            if(sum[i]){
                ans_wuren=max(ans_wuren,wuren);
                wuren=0;
                youren++;
            }else{
                ans_youren=max(ans_youren,youren);
                youren=0;
                wuren++;
            }
        }
        cout<<ans_youren<<" "<<ans_wuren<<endl;
        return 0;
    }

    另一种做法,洛谷的标签是线段树,题解中有个用线段树离散化做的,把每一个时间段看成一个点,

    点值为时间长短,把空闲时间的点值看做负数,最后求最大值和最小值的负数即可。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    #define  maxn 5009
    #define lson rt<<1,l,mid 
    #define rson rt<<1|1,mid+1,r 
    
    int n,z[maxn];
    
    struct T{
        int l,r;
        bool operator < (const T &a)const {
            return l<a.l;
        }
    }t[maxn];
    
    struct Tree{
        int minl,maxl;
    }tr[maxn<<2];
    
    void update(int rt){
        tr[rt].minl=min(tr[rt<<1].minl,tr[rt<<1|1].minl);
        tr[rt].maxl=max(tr[rt<<1].maxl,tr[rt<<1|1].maxl);
    }
    
    void build(int rt,int l,int r){
        if(l==r){
            tr[rt].minl=min(0,z[l]);
            tr[rt].maxl=z[l];
            return;
        }
        int mid=(l+r)>>1;
        build(lson);build(rson);
        update(rt);
        return;
    }
    
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d%d",&t[i].l,&t[i].r);
            sort(t+1,t+n+1);
        int p=0,ll=t[1].l,rr=t[1].r;
        for(int i=1;i<=n;i++){
            if(t[i].l>=ll&&t[i].r<=rr)continue;
            if(t[i].l<=rr&&t[i].r>rr)rr=t[i].r;
            else {
                z[++p]=rr-ll;
                z[++p]=-(t[i].l-rr);
                ll=t[i].l;rr=t[i].r;
            }
        }
        z[++p]=rr-ll;
        build(1,1,p);
        printf("%d %d",tr[1].maxl,-tr[1].minl);
        return 0;
    }
  • 相关阅读:
    混淆
    【虚拟DOM】√
    fn
    notebook
    sourceMappingURL
    十进制转换为十六进制
    关于this和super的区别
    类中访问级别
    Java中字符串解析
    IWorkspace操作
  • 原文地址:https://www.cnblogs.com/zzyh/p/7568812.html
Copyright © 2011-2022 走看看