noip2013 火柴排隊

2021-07-16 14:16:45 字數 2063 閱讀 5895

涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。 現在將每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 兩列火柴之間的距離定義為: ∑(ai-bi)^2

其中 ai 表示第一列火柴中第 i 個火柴的高度,bi 表示第二列火柴中第 i 個火柴的高度。

每列火柴中相鄰兩根火柴的位置都可以交換,請你通過交換使得兩列火柴之間的距離最小。請問得到這個最小的距離,最少需要交換多少次?如果這個數字太大,請輸出這個最小交換次數對 99,999,997 取模的結果。

輸入格式:

輸入檔案為 match.in。

共三行,第一行包含乙個整數 n,表示每盒中火柴的數目。

第二行有 n 個整數,每兩個整數之間用乙個空格隔開,表示第一列火柴的高度。

第三行有 n 個整數,每兩個整數之間用乙個空格隔開,表示第二列火柴的高度。

輸出格式:

輸出檔案為 match.out。

輸出共一行,包含乙個整數,表示最少交換次數對 99,999,997 取模的結果。

輸入樣例#1:

【輸入輸出樣例 1】

42 3 1 4

3 2 1 4

【輸入輸出樣例 2】

41 3 4 2

1 7 2 4

輸出樣例#1:

【輸入輸出樣例 1】

1【輸入輸出樣例 2】

2

【輸入輸出樣例說明1】

最小距離是 0,最少需要交換 1 次,比如:交換第 1 列的前 2 根火柴或者交換第 2 列的前 2 根火柴。

【輸入輸出樣例說明2】

最小距離是 10,最少需要交換 2 次,比如:交換第 1 列的中間 2 根火柴的位置,再交換第 2 列中後 2 根火柴的位置。

【資料範圍】

對於 10%的資料, 1 ≤ n ≤ 10;

對於 30%的資料,1 ≤ n ≤ 100;

對於 60%的資料,1 ≤ n ≤ 1,000;

對於 100%的資料,1 ≤ n ≤ 100,000,0 ≤火柴高度≤ maxlongint

思路:為了求最小的sigma,我們需要將每列的火柴高度有序化,此時問題就可以看成:要將火柴列a,b都轉化成有序數列需要的交換次數。

那麼,求有序轉化的交換次數的問題,也可以看成求序列逆序對過程,而此題的難點就是需要我們求雙序列逆序對。

首先解決單序列的逆序對問題,這裡我考慮用我最熟悉的資料結構:樹狀陣列(當然線段樹也同樣是解題利器,只不過改點求區間樹狀陣列更簡潔,優雅)。

演算法過程1:利用逆序對定義「1」,陣列a中,若ia[j],則構成一對逆序對,我們可以這樣設計:

確定樹狀陣列代表的是乙個數域,即陣列a中元素值構成的乙個區間,而維護區間中數存在的個數(想象桶排序是怎麼做的?)。

從1到n遍歷陣列a,用a[i]的值更新數域。

因為當前樹狀陣列中1~a[i]維護就是陣列中下標小於i、且小於a[i]的數的個數,令這個數為t,所以已經納入樹狀陣列的數的個數i(已經更新了i個數,對吧?)-t=已經更新過卻大於a[i]的數的個數s,利用「1」,得出s=當前數構成逆序對的個數。

輸出s,演算法完成。

其次,我們再解決雙序列逆序對問題。

演算法過程2:有什麼想法呢?無非和陣列下標和鍵值有關,看看題幹「0 ≤火柴高度≤ maxlongint」,這就說明我們不可拿火柴高度作為樹狀陣列下標,所以實現存下每根火柴在原陣列中的下標a'和b',以火柴高度為關鍵字對陣列a和b排一下序,根據a'為下標,把b'作為鍵值,放入陣列c中,構成乙個次序序列,再用c作為樹狀陣列下標進行演算法1操作。

問題解答完畢。

#include#include#include#define modnum 99999997

using namespace std;

int c[100001],d[100001],n,ans;

struct box

int main()

printf("%d\n",ans%modnum);

return 0;

}

NOIP2013 火柴排隊

題目 分析 a中第幾大一定對應b中第幾大。ab同時移動相當於a移動,相對位置不變。所以,用c i 表示a i 需要移動到的 位置,求其中的逆序對。因為乙個每移動相鄰兩個元素相當於消除乙個逆序對。include include using namespace std const int tmax 10...

NOIP 2013 火柴排隊

題目描述 description 涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。現在將每盒中的火柴各自排成一列,同一列火柴的高度互不相同,兩列火柴之間的距離定義為 其中 ai表示第一列火柴中第 i 個火柴的高度,bi表示第二列火柴中第 i 個火柴的高度。每列火柴中相鄰兩根火柴的位置都可...

NOIp2013 火柴排隊

描述 涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。現在將每盒中的火柴各自排成一列,同一列火柴的高度互不相同,兩列火柴之間的距離定義為 每列火柴中相鄰兩根火柴的位置都可以交換,請你通過交換使得兩列火柴之間的距離最 小。請問得到這個最小的距離,最少需要交換多少次?如果這個數字太大,請輸出...