题目链接:http://cogs.pro:8081/cogs/problem/problem.php?pid=vimiQkqjU
【题目描述】
样例一输入:
4
2 3 1 4
3 2 1 4
样例二输入:
4
1 3 4 2
1 7 2 4
思路:对于两盒火柴,最小距离∑(1≤i≤n)(ai - bi)2 可推出只与ai*bi有关,又可知顺序的值大于等于乱序的值,因此只需要将A与B的顺序做成一样的即可,第一想法是考虑升序 或者降序,但是要求交换次数最小,则可取其中一个不动,另外一个的相对顺序变成一样的即可,代码中a[i]表示b的位置,i表示a的第i个元素,则只需要把a进行逆序对统计即可。
代码如下:
1 #include "iostream" 2 #include "cstdio" 3 #include "algorithm" 4 #define maxn 100100 5 #define ll long long 6 using namespace std; 7 8 struct stick 9 { 10 int length, id; 11 bool operator < (const stick& a)const 12 { 13 return length < a.length; 14 } 15 }s[maxn], d[maxn]; 16 17 ll temp[maxn], n, a[maxn]; 18 ll sum = 0; 19 20 void merge(ll b[], ll l, ll r) 21 { 22 for (int i = l; i <= r; i++) 23 { 24 temp[i] = b[i]; 25 } 26 int mid = (l + r) >> 1; 27 int i = l, j = mid + 1; 28 for (int pos = l; pos <= r; pos++) 29 { 30 if (i == mid + 1) 31 { 32 a[pos] = temp[j]; 33 j++; 34 } 35 else if (j == r + 1) 36 { 37 a[pos] = temp[i]; 38 i++; 39 } 40 else if (temp[i] > temp[j]) 41 { 42 a[pos] = temp[j]; 43 j++; 44 sum += mid - i + 1; 45 sum %= 99999997; 46 } 47 else 48 { 49 a[pos] = temp[i]; 50 i++; 51 } 52 } 53 } 54 55 void msort(ll b[], ll l, ll r) 56 { 57 if (l == r) 58 return; 59 int mid = (l + r) >> 1; 60 msort(b, l, mid); 61 msort(b, mid + 1, r); 62 merge(b, l, r); 63 } 64 65 int main() 66 { 67 freopen("MatchNOIP2013.in", "r", stdin); 68 freopen("MatchNOIP2013.out", "w", stdout); 69 cin >> n; 70 for (int i = 0; i < n; i++) 71 { 72 cin >> s[i].length; 73 s[i].id = i; 74 } 75 for (int i = 0; i < n; i++) 76 { 77 cin >> d[i].length; 78 d[i].id = i; 79 } 80 sort(s, s + n); 81 sort(d, d + n);//排序后方便将id离散化 82 for (int i = 0; i < n; i++) 83 { 84 a[s[i].id] = d[i].id; 85 } 86 msort(a, 0, n - 1); 87 cout << sum % 99999997 << endl; 88 return 0; 89 }