您的位置:首页 > 其它

UVALive 6656 Watching the Kangaroo(二分)

2015-09-15 22:36 405 查看
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=48738

题意:给你一些区间,再查询一些点,问这些点与所有区间形成的最小距离的最大值。最小距离定义为:如果点在区间内,那么最小距离为0,否则为min(pos-L[i],R[i]-pos)。

题解:按区间中点排序,每个中点能到大的最左最右值,在二分查找第一个大于等于pos的中点值,假设查找到的下标为i, 则ans为max(pos-mi[i],ma[i]-pos).

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <set>
#include <queue>

using namespace std;
const int maxn=1e5+100;
const int INF=2e9;

struct T {
    int l,r,z;
    bool operator < (const T & a) const {
        return z<a.z;
    }
};

T s[maxn];
int n,m;
int mi[maxn];
int ma[maxn];

void get_mi() {
    mi
=s
.l;
    mi[n+1]=INF;
    for(int i=n-1; i>=1; i--) {
        mi[i]=min(s[i].l,mi[i+1]);
    }
}

void get_ma() {
    ma[1]=s[1].r;
    for(int i=2; i<=n; i++)
        ma[i]=max(s[i].r,ma[i-1]);
}

int main() {
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt","r",stdin);
#endif
    int t,ca=1;
    scanf("%d",&t);
    while(t--) {
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; i++) {
            scanf("%d%d",&s[i].l,&s[i].r);
            s[i].z=(s[i].l+s[i].r)/2;
        }
        sort(s+1,s+n+1);
        get_mi();
        get_ma();
        printf("Case %d:\n",ca++);
        for(int i=0; i<m; i++) {
            T x;
            scanf("%d",&x.z);
            int j=lower_bound(s+1,s+1+n,x)-s;
            int ans=0;
            if(mi[j]<=x.z)
                ans=max(ans,x.z-mi[j]);
            if(ma[j-1]>=x.z)
                ans=max(ans,-x.z+ma[j-1]);
            printf("%d\n",ans);
        }
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: