涵涵有兩盒火柴,每盒裝有 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.