• 火柴排队(codevs 3286)题解


    【问题描述】

    涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:,其中 ai表示第一列火柴中第 i 个火柴的高度,bi表示第二列火柴中第 i 个火柴的高度。每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对 99,999,997 取模的结果。

    【样例输入1】

        4 
        2 3 1 4 
        3 2 1 4

    【样例输出1】

        1

    【样例输入2】

        4 
        1 3 4 2 
        1 7 2 4

    【样例输出2】

        2

    【解题思路】

         本题为NOIP2013提高组day1第二题,初看这道题目,天啊,好难!又要移动两个序列,又要找最小步数。其实仔细研究一下,会发现一点也不难。

        首先,不需要移动两个序列,移动一个序列是等价的(最终结果相同),因此,我们只需移动一个序列。

       其次,本题的解法是非常简单的,我们可以确定,要使两个队列的距离最小,那么需要两个队列每一个位置上的高度差最小,因此,我们只需要把两个序列的高度排列的顺序换到相同就行了。我们来研究一下样例1:

       样例一中2、3、1、4从小到大排列后变成了1、2、3、4,1、2、3、4在序列中所对应的序号为3、1、2、4,因此,根据我们刚才得出的解法,只要把序列二的从小到大的排列放在3、1、2、4的位置上就行了。现在我们将序列二从小到大排列,变成了1、2、3、4,在序列二中所对应的序号为3、2、1、4,我们新建一个序列三,设序列三为c,c[i]表示在序列二中序号为i的数需要放在第c[i]个,因此,序列三为2、1、3、4,即对于第x个数,它在序列二所对的序号为i,在序列一中的序号为c[i],这样,c数组就出来了,剩下的事情就是求逆序对个数了,注意边求边取模即可。

    【代码实现】

     1 type rec=record
     2      xh,data:longint;
     3 end;
     4      arr=array[0..100010] of rec;
     5 var a,b:arr;
     6     c,t:array[0..100010] of longint;
     7     ans,i,j,n,min,minj,y:longint;
     8 procedure sort(l,r:longint;var a:arr);
     9       var
    10          i,j,x:longint;
    11          y:rec;
    12       begin
    13          i:=l;
    14          j:=r;
    15          x:=a[(l+r) div 2].data;
    16          repeat
    17            while a[i].data<x do
    18             inc(i);
    19            while x<a[j].data do
    20             dec(j);
    21            if not(i>j) then
    22              begin
    23                 y:=a[i];
    24                 a[i]:=a[j];
    25                 a[j]:=y;
    26                 inc(i);
    27                 j:=j-1;
    28              end;
    29          until i>j;
    30          if l<j then
    31            sort(l,j,a);
    32          if i<r then
    33            sort(i,r,a);
    34       end;
    35 procedure gb(l,r:longint);
    36 var i,j,p,mid:longint;
    37 begin
    38  if l=r then exit;
    39  mid:=(l+r)div 2;
    40  gb(l,mid);
    41  gb(mid+1,r);
    42  i:=l;p:=l;j:=mid+1;
    43  while(i<=mid)and(j<=r)do
    44   if c[i]<=c[j] then
    45    begin
    46     t[p]:=c[i];inc(p);inc(i);
    47    end
    48   else
    49    begin
    50     ans:=(ans+mid-i+1)mod 99999997;t[p]:=c[j];inc(p);inc(j);
    51    end;
    52  while i<=mid do
    53   begin
    54    t[p]:=c[i];inc(p);inc(i);
    55   end;
    56  while j<=r do
    57   begin
    58    t[p]:=c[j];inc(p);inc(j);
    59   end;
    60  for i:=l to r do
    61   c[i]:=t[i];
    62 end;
    63 begin
    64  readln(n);
    65  for i:=1 to n do
    66   begin
    67    read(a[i].data);
    68    a[i].xh:=i;
    69   end;
    70  for i:=1 to n do
    71   begin
    72    read(b[i].data);
    73    b[i].xh:=i;
    74   end;
    75  sort(1,n,a);
    76  sort(1,n,b);
    77  for i:=1 to n do
    78   c[b[i].xh]:=a[i].xh;
    79  gb(1,n);
    80  writeln(ans);
    81 end.
  • 相关阅读:
    jQuery 集合 搜索操作(父辈元素搜索、同辈元素搜索、子元素搜索)
    struts <s:form action=""> 和 <s:submit action=""> 的区别
    654. 最大二叉树
    701. 二叉搜索树中的插入操作
    617. 合并二叉树
    98. 验证二叉搜索树
    236. 二叉树的最近公共祖先
    700. 二叉搜索树中的搜索
    235. 二叉搜索树的最近公共祖先
    105. 从前序与中序遍历序列构造二叉树
  • 原文地址:https://www.cnblogs.com/PengBoLiuXu/p/4536232.html
Copyright © 2020-2023  润新知