特长生模拟 Distinct (二分)

4 Distinct

1s; 256M
4.1 题目描述
Daniel 正在玩一个战棋游戏。
现在Daniel 有n 队士兵站在x 轴上。第i 队士兵有ai 人,坐标为xi。
Daniel 看到一队士兵有这么多人,都站在同一个位置,他对此很不满意。他
想命令一些士兵移动到新的位置(必须是整点),使得不存在两个士兵站在同一个
位置。
为了节约时间,Daniel 希望每个士兵的移动距离的最大值尽可能小。请求出
这个最小值。
4.2 输入格式
第一行一个正整数n,表示Daniel 有多少队士兵。
第二行n 个正整数ai,表示每队士兵的人数。
第三行n 个严格递增的整数xi,表示每队士兵的坐标。
4.3 输出格式
一行一个非负整数,表示每个士兵的移动距离的最大值的最小值。

分析:二分答案,然后检验是否可行,把每队士兵先放到左边放完再放右边,以此类推。

代码

const
  maxn=200000;
var
  a,x:array[0..maxn] of int64;
  n,i,s:longint;

function check(m:int64):boolean;
var
  i:longint;
  k:int64;
begin
  k:=x[1]-m;
  for i:=1 to n do
    begin
      if k<x[i]-m then k:=x[i]-m;
      if x[i]+m-k+1<a[i] then exit(false);
      k:=k+a[i];
    end;
  exit(true);
end;

procedure find(l,r:int64);
var
  mid:int64;
begin
  mid:=(l+r) div 2;
  if l=r then
    begin
      writeln(l);
      close(input);close(output);
      halt;
    end;
  if check(mid) then find(l,mid) else find(mid+1,r);
end;

begin
  assign(input,'distinct.in');reset(input);
  assign(output,'distinct.out');rewrite(output);
  readln(n);
  for i:=1 to n do
    read(a[i]);
  for i:=1 to n do
    read(x[i]);
  find(0,1234567891234567);
  close(input);close(output);
end.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值