2154: E.wjw的排队问题
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 8 Solved: 5
[ Submit][ Status][ Web Board]
Description
wjw作为班里的学习委员,虽然是个学习委员,但是谁让班长ly经常不靠谱呢,每次当ly不靠谱的时候,总是需要wjw帮她解决问题...现在临近体育课,ly拿到了你的代码但是没办法运行,于是傻乎乎的去找电脑了...但是眼看着马上就要上课了,班里的同学还三三两两的几个人围在一起聊天,wjw没有办法,一下子让所有人按身高排序是来不及了,所以wjw决定用最快的速度让所有人排好队,不要求身高,只要每个人不站在一起就可以了...
现在机智的wjw所有人抽象在一条X轴上,在这条X轴的一些整数坐标上,存在很多小团体,第i个小团体的人数是a[i],所在的坐标是b[i]。
现在wjw要让这些人每个人站在一个整数坐标点上,并且使得没有两个人在同一个点上。
为了节约时间,wjw希望每个人的移动距离的最大值最小,请你求出这个最小值
Input
只有一组数据
第一行一个正整数n,表示有多少个小团体
第二行n个正整数a[i],表示第i个小团体的人数
第三行n个严格递增的整数b[i],表示第i个小团体的坐标
Output
一行一个非负整数,表示每个人的移动距离的最大值的最小值
Sample Input
2
2 3
0 2
Sample Output
1
[分析]
二分答案然后check,check方式很简单...所有点的人优先往左移,然后往右移就可以了
原因随便脑补一下,最优的方式肯定是从当前点x左右扩散到[x-mid,x+mid],那么为了方便下一个点的人移动,所以每个点的人肯定是优先向左移动的
[代码]
#include <stdio.h>
#define maxn 100001
#define INF 0x7f7f7f7f
int a[maxn], b[maxn];
int n;
int chack(int t)
{
int l = -INF;
for (int i = 1; i <= n; i++)
{
int xl = b[i] - t, xr = b[i] + t;
if (l < xl) l = xl;
if (l + a[i] - 1 > xr) return 0;
l += a[i];
}
return 1;
}
int main()
{
//freopen("5.in", "r", stdin);
//freopen("5.out", "w", stdout);
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
int l = -1, r = INF;
while (l + 1 < r)
{
int m = (l + r) >> 1;
int xx = chack(m);
if (xx == 1) r = m;
else l = m;
}
printf("%d\n", r);
}