1. 程式人生 > >E、CSL 的魔法 【模擬】 (“新智認知”杯上海高校程序設計競賽暨第十七屆上海大學程序設計春季聯賽)

E、CSL 的魔法 【模擬】 (“新智認知”杯上海高校程序設計競賽暨第十七屆上海大學程序設計春季聯賽)

ems data- close 設計 ref ida mathjax 認知 ans

題目傳送門:https://ac.nowcoder.com/acm/contest/551#question

題目描述

有兩個長度為 n 的序列,a0,a1,,an1a0,a1,…,an−1和 b0,b1,,bn1b0,b1,…,bn−1。CSL 有一種魔法,每執行一次魔法,可以任意挑選一個序列並任意交換序列中兩個元素的位置。CSL 使用若幹次魔法,得到最終的序列 a 和 b,並且想要讓 a0b0+a1b1++an1bn1a0b0+a1b1+…+an−1bn−1的值最小化。求解 CSL 至少使用多少次魔法,能夠達到最小化的目標。

輸入描述:

第一行有一個整數 n,表示序列的長度。

接下來兩行,每行有 n 個整數,分別表示初始序列 a 和 b。

輸入數據保證每個序列裏的數兩兩不同。 2n1052≤n≤105
1ai,bi1091≤ai,bi≤109

輸出描述:

在一行輸出一個整數,表示最少使用的魔法次數。
示例1

輸入

復制
2
1 2
1 2

輸出

復制
1
示例2

輸入

復制
2
1 2
2 1

輸出

復制
0

解題思路:

註意一個bug點即可:

給出的a b 序列的數不一定相同。

所以對於 兩個序列都要進行排序,然後map映射一下原序列每個數對應的位置,每個數的排名。

然後以其中一個序列為參考,掃一遍,最大的匹配另一個序列裏最小的,不能匹配則交換序列裏兩個數的位置。

AC code:

技術分享圖片
 1 #include <bits/stdc++.h>
 2 #define INF 0x3f3f3f3f
 3 #define LL long long
 4 #define inc(i, j, k) for(int i = j; i <= k; i++)
 5 #define rep(i, j, k) for(int i = j; i < k; i++)
 6
#define mem(i, j) memset(i, j, sizeof(i)) 7 #define gcd(i, j) __gcd(i, j) 8 using namespace std; 9 const int MAXN = 2e5+10; 10 map<int, int>ida, idb, xa, xb; 11 int a[MAXN], b[MAXN], tpa[MAXN], tpb[MAXN]; 12 13 bool cmp(int a, int b) 14 { 15 return a > b; 16 } 17 int N; 18 19 int main() 20 { 21 scanf("%d", &N); 22 inc(i, 1, N){ scanf("%d", &a[i]); tpa[i] = a[i]; xa[a[i]] = i;} 23 inc(i, 1, N){ scanf("%d", &b[i]); tpb[i] = b[i]; xb[b[i]] = i;} 24 sort(tpa+1, tpa+1+N); 25 inc(i, 1, N) ida[tpa[i]] = i; 26 sort(tpb+1, tpb+1+N, cmp); 27 inc(i, 1, N) idb[tpb[i]] = i; 28 int ans = 0; 29 inc(i, 1, N) 30 { 31 if(ida[a[i]] != idb[b[i]]){ 32 ans++; 33 int nxtb = tpb[ida[a[i]]]; 34 int nxt = xb[nxtb]; 35 xb[b[i]] = nxt; 36 xb[b[nxt]] = i; 37 swap(b[i], b[nxt]); 38 } 39 } 40 41 printf("%d\n", ans); 42 return 0; 43 }
View Code

E、CSL 的魔法 【模擬】 (“新智認知”杯上海高校程序設計競賽暨第十七屆上海大學程序設計春季聯賽)