蚂蚁运输
题目描述:
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 想让蚂蚁运输完货物的时间尽可能短,你能帮帮它吗?
输入格式:
第一行两个数 n,m, n 表示 li,ri 的最大值。
接下来 m 行,每行两个数 li,ri。
输出格式:
一个数表示答案
输入样例
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 都行。
思路:
二分答案
读入时保证li<=ri
无视掉ri==li的情况
chaeck(mid)时
设建的传送站为X_Y
abs(l-X)+abs(r-Y)<=mid
则要求
l-X+r-Y<=mid
l-X+Y-r<=mid
X-l+r-Y<=mid
X-l+Y-r<=mid
则
l+r-mid<=X+Y<=l+r+mid
l-r-mid<=X-Y<=l-r+mid
只要存在X,Y对于所有的l,r满足上面两条件即可
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=1000010;
const int inf=0x7fffffff;
int n,m,tot;
struct node
{
int l;
int r;
}a[maxn];
bool can(int mid)
{
int l=-inf,r=inf;
for(int i=1;i<=tot;i++)
{
if(a[i].r-a[i].l<=mid) continue;
l=max(l,a[i].l+a[i].r-mid);
r=min(r,a[i].l+a[i].r+mid);
}
if(l>r) return 0;
l=-inf,r=inf;
for(int i=1;i<=tot;i++)
{
if(a[i].r-a[i].l<=mid) continue;
l=max(l,a[i].l-a[i].r-mid);
r=min(r,a[i].l-a[i].r+mid);
}
if(l>r) return 0;
return 1;
}
int main()
{
freopen("ant.in","r",stdin);
freopen("ant.out","w",stdout);
int x,y;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
if(x==y) continue;
if(x>y) swap(x,y);
a[++tot].l=x;
a[tot].r=y;
}
int l=0,r=n,mid,ans;
while(l<=r)
{
mid=(l+r)>>1;
if(can(mid))
{
r=mid-1;
ans=mid;
}
else l=mid+1;
}
cout<<ans;
fclose(stdin);fclose(stdout);
return 0;
}