【問題描述】
涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。現在將每盒中的火柴各自 排成一列,同一列火柴的高度互不相同,兩列火柴之間的距離定義為:∑i
=1n(
ai−b
i)2
其中 ai 表示第一列火柴中第 i 個火柴的高度,bi 表示第二列火柴中第 i 個火柴的高度。 每列火柴中相鄰兩根火柴的位置都可以交換,請你通過交換使得兩列火柴之間的距離最小。請問得到這個最小的距離,最少需要交換多少次?如果這個數字太大,請輸出這個最小交換次數對 99,999,997 取模的結果。
【輸入】
輸入檔案為 match.in。 共三行,第一行包含乙個整數 n,表示每盒中火柴的數目。 第二行有 n 個整數,每兩個整數之間用乙個空格隔開,表示第一列火柴的高度。 第三行有 n 個整數,每兩個整數之間用乙個空格隔開,表示第二列火柴的高度。
【輸出】
輸出檔案為 match.out。 輸出共一行,包含乙個整數,表示最少交換次數對 99,999,997 取模的結果。
【輸入輸出樣例 1】
match.in
match.out42
2 3 1 4
3 2 1 4
【輸入輸出樣例說明】
最小距離是 0,最少需要交換 1 次,比如:交換第 1 列的前 2 根火柴或者交換第 2 列的前 2 根火柴。
【輸入輸出樣例 2】
match.in
match.out42
1 3 4 2
1 7 2 4
【輸入輸出樣例說明】
最小距離是 10,最少需要交換 2 次,比如:交換第 1 列的中間 2 根火柴的位置,再交換第 2 列中後 2 根火柴的位置。
【資料範圍】
對於 10%的資料, 1 ≤ n ≤ 10;
對於 30%的資料,1 ≤ n ≤ 100;
對於 100%的資料,1 ≤ n ≤ 100,000,0 ≤火柴高度≤ 2^32 − 1。
【解題思路】
首先如果要解決這道題,就需要先了解一下什麼叫排序不等式。排序不等式完整說明如下:
設數列a=,b=且滿足a1≤a2≤a3≤…≤an,b1≤b2≤b3≤…≤bm。如果c=且c為b中元素的任意乙個排列那麼有如下概念:
將a1b1+a2b2+a3b3+…+anbm稱為順序積之和,簡稱順序和;
將a1bm+a2b m-1 +a3b m-2+…+anb1稱為逆序積之和,簡稱逆序和;
將a1c1+a2c2+a3c3+…+ancn稱為亂序積之和,簡稱亂序和。
那麼有順序和>亂序和>逆序和。①
了解了什麼叫排序不等式,那麼這題看起來就簡單多了。首先把距離公式變一下形,得到:(a
1−b1
)2+(
a2−b
2)2+
(a3−
b3)2
+...
+(an
−bn)
2 去括號得到:(a
12+a
22+a
32+.
..+a
n2+b
12+b
22+b
32+.
..+b
n2)−
2(a1
b1+a
2b2−
...+
anbn
) 由於所有火柴的高度是給定的,所以a1
2+a2
2+a3
2+..
.+an
2+b1
2+b2
2+b3
2+..
.+bn
2 是確定的。
那麼我們只需要a1
b1+a
2b2+
...+
anbn
最大即可。
由以上給出的排序不等式可知,當a1<a2<a3<…<an,b1<b2<b3<…<bn時,整體距離最小。
所以我們可以先將火柴高度陣列a和b進行排序,再將a中最高與b中最高的火柴序號,a中次高與b中次高的火柴序號,…,a中最矮與b中最矮的火柴序號分別進行對映。
對於樣例1,我們建立的對映就如這樣所示:
1 2 3 4
2 1 3 4
對於樣例2,建立的對映就是這樣:
1 2 3 4
1 4 2 3
而進行一次交換就可以消除掉一對逆序對,那麼問題的解即是求對映後下面那個陣列的逆序對個數。至此,問題解決完畢。
可以寫出如下程式:
#include
#include
#include
#define maxn 101101
#define mod 99999997
using
namespace
std;
long
long i,n,ans=0;
struct matcha[maxn],b[maxn];
int num[maxn]=,t[maxn]=;
int comp(match s,match k)
else t[k++]=num[i++];
while(i<=mid)t[k++]=num[i++];
while(j<=r)t[k++]=num[j++];
for(i=l;i<=r;i++)num[i]=t[i];
}int main()
for(i=1;i<=n;i++)
sort(a+1,a+1+n,comp);
sort(b+1,b+1+n,comp);
for(i=1;i<=n;i++)num[a[i].id]=b[i].id;
merge(1,n);
printf("%lld",ans);
return
0;}
①:嚴格來說,這個不等式是順序和≥亂序和≥逆序和,且當a1=a2=a3=…=an或b1=b2=b3=…=bn時順序和=逆序和。並且當c數列中元素排列順序和b數列中一樣時亂序和=順序和。但是此題中每列中火柴高度都不相同,所以等號無法成立。 NOIP2013提高組 火柴排隊
題目大意 給你兩個有序陣列a,b並定義a,b間的距離為 ai bi 2,要求交換a或者b中的某些元素的位置使得a,b間距離最小。由於 ai bi 2 ai 2 bi 2 2 aibi 而由於題目給定了ai,bi的值,所以 ai 2 bi 2 是定值,要求原式最小就需要 aibi最大。而根據排序不等式...
NOIP2013提高組 火柴排隊
noip2013 提高組 day1 試題 涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。現在將每盒中的火柴各自排成一列,同一列火柴的高度互不相同,兩列火柴之間的距離定義為 其中 ai 表示第一列火柴中第 i個火柴的高度,bi 表示第二列火柴中第 i 個火柴的高度。每列火柴中相鄰兩根火柴...
NOIP2013提高組 火柴排隊
ai bi 2 ai2 bi2 2 ai bi,要使 ai bi 2最小,則需2 ai bi最大。由排序不等式可知兩列數字裡第一大與第一大對應,第二大與第二大對應,第k大與第k大對應,第n大與第n大對應時,ai bi最大。故先將第一列每個數字對映到第二列排名相同的數字,再求需要交換的次數,也就是逆序...