jzoj3619 medians

Description

让我们定义A 为1, 2, 3,。。。, 2 * N - 1 的一个全排列。

定义数列B 为A 的前缀的中位数形成的数列:B[i] 为A[1],A[2],。。。,A[2 * i - 1] 的中位数。

注:对于M 个数的中位数(M 是奇数),可以通过排序后取中间的数得到。

给出N 和数列B。找到一个全排列A 使得前缀中位数形成的数列恰好为B。

Input

输入包含两行。

第一行包含一个整数N。

第二行描述B:N 个整数,用空格隔开。

Output

输出A:含2 * N - 1 个空格隔开的整数的一行。如果有多个全排列A 能够形成输入的数列B,

那么你可以输出任意一个。测试数据中保证总是存在解。

Sample Input

5

1 3 3 4 5

Sample Output

1 9 3 2 4 8 7 5 6

Data Constraint

• 1 <= A[i] <= 2 * N - 1,对于任意i 从1 到2 * N - 1

• 1 <= B[i] <= 2 * N - 1,对于任意i 从1 到N

• 1 <= N <= 100 000

• 60% 的数据有N <= 1000

算法讨论

从左往右贪心,a序列共有三种情况,记录l,r分别为1~2*n-1中最小和最大的没放入b序列的值
(1)a[i]=a[i-1]
   那么输出l,r,更新l和r
(2)a[i]>a[i-1]
   如果a[i]已放入,输出两次r,否则输出a[i]和r
(3)a[i]<a[i-1]
   如果a[i]已放入,输出两次l,否则输出a[i]和l
var
  f:array[0..200000] of boolean;
  a:array[0..200000] of longint;
  n,i,l,r,p:longint;
procedure jj;
begin
  write(l,' ');
  f[l]:=true;
  while (f[l])and(l<2*n-1) do
    inc(l);
  if l>r then
    begin p:=r;r:=l;l:=p;end;
end;
procedure jjj;
begin
  write(r,' ');
  f[r]:=true;
  while (f[r])and(r>0) do
    dec(r);
  if r<l then
    begin p:=r;r:=l;l:=p;end;
end;
begin
  assign(input,'medians.in');reset(input);
  //assign(output,'medians.out');rewrite(output);
  readln(n);
  for i:=1 to n do
    read(a[i]);

  f[a[1]]:=true;
  write(a[1],' ');
  l:=1;
  while f[l] do inc(l);
  r:=2*n-1;
  while f[n] do dec(r);
  for i:=2 to n do
    begin
      if a[i]=a[i-1] then
        begin
          jj;
          jjj;
        end;
      if a[i]>a[i-1] then
        if f[a[i]] then
          begin
            jjj;jjj;
          end
        else
          begin
            write(a[i],' ');
            f[a[i]]:=true;
            if f[l] then
              while f[l] do inc(l);
            if f[r] then
              while f[r] do dec(r);
            if l>r then
              begin p:=l;l:=r;r:=l;end;
            jjj;
          end;
      if a[i]<a[i-1] then
        if f[a[i]] then
          begin
            jj;jj;
          end
        else
          begin
            write(a[i],' ');
            f[a[i]]:=true;
            if f[l] then
              while f[l] do inc(l);
            if f[r] then
              while f[r] do dec(r);
            if l>r then
              begin p:=l;l:=r;r:=l;end;
            jj;
          end;
    end;
  close(input);close(output);
end.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值