Think:
1知识点:归并排序思想+逆序数理解
2反思:学习知识点的时候思考思想时候可以类比联想之前学过的知识点,本题目在理解归并排序时可以思考之前学习的两个有序链表的归并
以下为Accepted代码
#include <bits/stdc++.h>
using namespace std;
long long int cnt;
int a[104000];
void Merge(int a[], int low, int mid, int high);
void Merge_sort(int a[], int low, int high);/*归并排序*/
int main(){
int n, i;
scanf("%d", &n);
for(i = 0; i < n; i++)
scanf("%d", &a[i]);
cnt = 0;
Merge_sort(a, 0, n-1);
printf("%lld\n", cnt);
return 0;
}
void Merge_sort(int a[], int low, int high){
int mid;
if(low < high){
mid = (low + high)/2;
Merge_sort(a, low, mid);
Merge_sort(a, mid+1, high);
Merge(a, low, mid, high);
}
}
void Merge(int a[], int low, int mid, int high){/*可类比两组有序链表的归并,思想基本一样*/
int i = low;
int j = mid + 1;
int k = 0;
int *b = (int *)malloc((high - low + 1)*sizeof(int));/*动态申请内存*/
while(i <= mid && j <= high){
if(a[i] <= a[j])
b[k++] = a[i++];
else {
b[k++] = a[j++];
cnt += (mid - i + 1);/*归并两组有序数据,当a[i] > a[j], 则在区间[i, mid]的数据全部大于a[j],此时对于a[j]的逆序数为(mid - i + 1)*/
}
}
while(i <= mid){
b[k++] = a[i++];
}
while(j <= high){
b[k++] = a[j++];
}
for(k = 0, i = low; i <= high; i++, k++){
a[i] = b[k];
}
}
/***************************************************
User name:
Result: Accepted
Take time: 48ms
Take Memory: 8972KB
Submit time: 2017-07-15 10:31:30
****************************************************/