• 蚂蚁运输(ant)


    蚂蚁运输(ant)
    Time Limit:5000ms Memory Limit:64MB
    【题目描述】
      LYK 在观察一些蚂蚁。蚂蚁想要积攒一些货物来过冬。积攒货物的方法是这样的。对于第i只蚂蚁, 它要从li出发, 拿起货物, 走到ri处放下货物, 需要消耗的时间为|ri-li|。而且所有蚂蚁都是可以同时进行的,也就是说,假如有 m 只蚂蚁,那么运输完货物的时间为 max{|ri-li|}。LYK 决定帮蚂蚁一把,它发明了空间传输装置。具体地,当蚂蚁走到 X 处时,它可以不耗费任意时间的情况下瞬间到达 Y,或者从 Y 到达 X。也就是说,一个蚂蚁如果使用了空间传输装置,它耗费的时间将会是 min{|li-X|+|ri-Y|,|li-Y|+|ri-X|},当然蚂蚁也可以选择徒步走到目标点。由于空间传输装置非常昂贵,LYK 打算只建造这么一台机器。并且 LYK 想让蚂蚁运输完货物的时间尽可能短,你能帮帮它吗?

    【输入格式】(ant.in)
      第一行两个数 n,m,n 表示 li,ri 的最大值。
      接下来 m 行,每行两个数 li,ri。
    【输出格式】(ant.out)
      一个数表示答案
    【输入样例】
      5 2
      1 3
      2 4
    【输出样例】
      1
    【数据范围】
      对于 20%的数据 n,m<=100。
      对于 40%的数据 n,m<=1000。
      对于 60%的数据 n<=100000,m<=1000。
      对于 80%的数据 n,m<=100000。
      对于 100%的数据 n,m<=1000000,1<=li,ri<=n(li=ri 时你甚至可以无视这只蚂蚁) 。
    【样例解释】
      令空间传输装置的参数中 X=2,Y=3 或者 X=3,Y=2 都行。

    【题目分析】

      二分答案。假设最短时间为Zdsj,传送的区间为x——y

      首先预处理一下,如果l[i]==r[i],直接忽略这只蚂蚁,如果l[i]>r[i],我们把这两个数交换(反正正反走都是一样的),通过这样的处理之后就可以得到|L-x|+|R-y|<=Zdsj。

        L-x+R-y<=Zdsj;

        L-x+y-R<=Zdsj;

        x-L+R-y<=Zdsj;

        x-L+y-R<=Zdsj;

      整理一下可以得到:

        L+R-Zdsj<=x+y<=L+R+Zdsj;

        L-R-Zdsj<=x-y<=L-R+Zdsj;

      只要保证这两段区间内都有数就可以了,

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    const int maxn=1e7+10;
    const int INF=1e9;
    int n,m;
    int L[maxn],R[maxn];
    int ans=0;
    int c=0;
    int check(int Zdsj)
    {
        int l1=-INF,r1=INF;
        for(int i=1;i<=c;i++)
        {
            if(R[i]-L[i]<=Zdsj) continue;
            l1=max(l1,L[i]+R[i]-Zdsj);
            r1=min(r1,L[i]+R[i]+Zdsj);
        }
        if(l1>r1) return 0;
        l1=-INF;r1=INF;
        for(int i=1;i<=c;i++)
        {
            if(R[i]-L[i]<=Zdsj) continue;
            l1=max(l1,L[i]-R[i]-Zdsj);
            r1=min(r1,L[i]-R[i]+Zdsj);
        }
        if(l1>r1) return 0;
        return 1;
    }
    int main()
    {
        freopen("ant.in","r",stdin);
        freopen("ant.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            if(a>b) swap(a,b);
            if(a!=b)
                L[++c]=a,
                R[c]=b;
        }
        int l=0,r=n;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(check(mid))
                ans=mid,
                r=mid-1;
            else
                l=mid+1;
        }
        printf("%d
    ",ans);
        fclose(stdin);fclose(stdout);
        return 0;
    }
  • 相关阅读:
    Hdu-5983 2016ACM/ICPC亚洲区青岛站 B.Pocket Cube 模拟
    Codeforces Round #300 F
    cf298F:状压dp+剪枝
    POJ3294--Life Forms 后缀数组+二分答案 大于k个字符串的最长公共子串
    jzp线性筛及其简单应用
    Codeforces Round #299 (Div. 1)C. Tavas and Pashmaks (凸壳)
    Codeforces Round #236 (Div. 2)E. Strictly Positive Matrix(402E)
    【2012天津区域赛】部分题解 hdu4431—4441
    HDU4436---str2int 后缀树组(12年天津区域赛)
    Codeforces
  • 原文地址:https://www.cnblogs.com/xiaoningmeng/p/6046911.html
Copyright © 2020-2023  润新知