1. 程式人生 > >timus[1090. In the Army Now]

timus[1090. In the Army Now]

urn i++ str pro acm ret cin inversion max

timus[1090. In the Army Now]

看了一下題目的意思,求逆序數,求出逆序數最大的行號。

求逆序數是經典問題,想起當年剛學編程時,算法導論裏就有這個習題,如何將merge sort修改為可以計算逆序數的版本,於是寫了一下,得到了以下一份答案。

技術分享圖片
 1 #include <iostream>
 2 #include <algorithm>
 3 
 4 using namespace std;
 5 
 6 const int MAX_N = 10000;
 7 
 8 const int INF = MAX_N + 1;
 9 
10 int N, K;
11
12 int A[MAX_N]; 13 14 int aux[2][(MAX_N >> 1) + 1]; 15 16 int merge(int p, int mid, int q) 17 { 18 19 int left_length = mid + 1 - p; 20 int right_length = q - mid; 21 for (int i = 0; i < left_length; ++i) 22 { 23 aux[0][i] = A[p + i]; 24 } 25 aux[0][left_length] = INF;
26 27 for (int i = 0; i < right_length; ++i) 28 { 29 aux[1][i] = A[mid + 1 + i]; 30 } 31 aux[1][right_length] = INF; 32 int ans = 0; 33 int i = 0; 34 int j = 0; 35 for (int k = 0; k < left_length + right_length; ++k) 36 { 37 if (aux[0][i] < aux[1
][j]) 38 { 39 A[p + k] = aux[0][i++]; 40 } 41 else 42 { 43 A[p + k] = aux[1][j++]; 44 ans += left_length - i; 45 } 46 } 47 return ans; 48 } 49 50 int inversions(int p, int q) 51 { 52 int ans = 0; 53 if (p < q) 54 { 55 int mid = (p + q) / 2; 56 ans += inversions(p, mid); 57 ans += inversions(mid + 1, q); 58 ans += merge(p, mid, q); 59 } 60 return ans; 61 } 62 63 int main() 64 { 65 cin >> N >> K; 66 int ans; 67 int max_inversions = -1; 68 for (int k = 0; k < K; ++k) 69 { 70 for (int i = 0; i < N; ++i) 71 { 72 cin >> A[i]; 73 } 74 int x = inversions(0, N - 1); 75 if (x > max_inversions) 76 { 77 max_inversions = x; 78 ans = k + 1; 79 } 80 } 81 cout << ans << endl; 82 83 return 0; 84 }
Solution with merge sort.

timus[1090. In the Army Now]