ProblemDescription
公元 2222 年, l 国发生了一场战争。
小
其中有
m
种物资的运输方案,每种运输方案形如
这里有
n
个城市,第
由于高科技的存在,小
Y
想到了一种节省时间的好方案。在
但是为了防止混乱,只能设立这么一条传送站。
现在这些运输方案同时进行,小
在样例中,存在两条运输方案,分别是
1
号城市到
多组测试数据
第一行两个整数 n,m(1≤n,m≤1000000) 。
接下来
m
行,每行两个整数
Output
一个数表示答案。
Source
2016
”百度之星” - 初赛(
AstarRound2B
)
首先……最大值中的最小值……
看到这种问题就可以考虑二分,然后转判定性问题了。
二分的肯定是完成时间。二分出一个时间
k
后,时间比
那么根据花费时间就可以列出不等式来
|l[i]−L|+|r[i]−R|<=k
其中
l[i],r[i]
是运输计划的左右端点,
L,R
是要建的传送门的左右端点。
因为
k
都已经比两个东西的绝对值要大了,所以
(说白了就是把绝对值拆开……)
然后移项后可以得到两个不等式
r[i]+l[i]−k≤R+L≤r[i]+l[i]+k
r[i]−l[i]−k≤R−L≤r[i]−l[i]+k
所以对于每次二分的
k
,
然后只要不等式能有解,就代表可行。
需要注意的是,不可解有两种情况
第一种:不等式下界大于上界;
第二种:
L,R
无整数解(当且仅当
L+R,L−R
有唯一确定解,且奇偶性不同)
#include<stdio.h>
#include<algorithm>
#define N 1000050
#define inf 2147483647
using namespace std;
int L,R,n,m,l[N],r[N],p1_lo,p2_lo,p1_up,p2_up,mid;
inline bool check(const int &k)
{
p1_lo=-inf,p2_lo=-inf,p1_up=inf,p2_up=inf;
for (int i=0;i<m;i++) if (k<r[i]-l[i])
{
p1_lo=max(p1_lo,r[i]+l[i]-k);
p1_up=min(p1_up,r[i]+l[i]+k);
p2_lo=max(p2_lo,r[i]-l[i]-k);
p2_up=min(p2_up,r[i]-l[i]+k);
if (!((p1_lo<=p1_up && p2_lo<=p2_up) && !(p1_lo==p1_up && p2_lo==p2_up && (p1_lo^p2_lo&1)))) return 0;
}
return 1;
}
int main()
{
while (~scanf("%d%d",&n,&m))
{
for (int i=0;i<m;i++)
{
scanf("%d%d",&l[i],&r[i]);
if (r[i]<l[i]) swap(l[i],r[i]);
}
for (L=0,R=n,mid=n>>1;L<R;mid=(L+R)>>1) if (check(mid)) R=mid;else L=mid+1;
printf("%d\n",L);
}
}