日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

LightHouse/归并排序

發布時間:2023/11/27 生活经验 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LightHouse/归并排序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

燈塔(LightHouse)

題目見https://dsa.cs.tsinghua.edu.cn/oj/problem.shtml?id=1144
最近復習DSA,便在看鄧老師的mooc,順便做做配套的題目,挺有意思的。

一、題目分析

簡述思路:兩次排序,第一次是對結構體的x坐標進行排序,第二次是計數y坐標中的逆序對/順序對的數目。
第一次排序可以采用快速排序/歸并排序等
第二次就是歸并排序計算逆序對數目

注意點如下:

  • 數據范圍大小,合適的地方需要使用long long,注意n*n結果范圍可能超過int,此時也需要long long n;
  • new和delete需要配合使用。int* B=new int[lenB];...delete[] B;否則會造成內存泄漏,oj顯示MLE
  • 歸并排序的歸并部分寫法,最優寫法如下
for(int i=0,j=0,k=0;i<lenB;){if(j>=lenC||B[i]<C[j]){A[k++]=B[i++];if(j<lenC)count+=(lenC-j);//順序對在這里出現}if(j< lenC&&C[j]<=B[i]){A[k++]=C[j++];//這里其實是逆序對}
}
  • 逆序對計數在歸并過程中自然進行即可,無需提前對B/C數組做二分查找。

    二、代碼實現

#include<cstdio>
#define MAX_NUM 4000006
typedef long long ll;
struct point{int x;int y;
};point origin[MAX_NUM];
int arr[MAX_NUM];
ll count;//順序對數目void MergeSort_X(point* p,int lo,int hi);
void MergeSort_Y(int* p,int lo,int hi);
void Merge_X(point* p,int lo,int mi,int hi);
void Merge_Y(int* p,int lo,int mi,int hi);int main(){int n;scanf("%d",&n );for(int i=0;i<n;i++){scanf("%d%d", &origin[i].x,&origin[i].y);}MergeSort_X(origin,0,n);//將origin數組按照X坐標升序排列for(int i=0;i<n;i++){arr[i]=origin[i].y;}MergeSort_Y(arr,0,n);//計算Y坐標中順序對的數目printf("%lld",count);
}//對數組p[lo,mi)按X坐標進行升序排序
void MergeSort_X(point* p,int lo,int hi){if(hi-lo<2)return;int mi=(lo+hi)/2;MergeSort_X(p,lo,mi);MergeSort_X(p,mi,hi);Merge_X(p,lo,mi,hi);
}//對數組p[lo,mi)和數組p[mi,hi)進行歸并
void Merge_X(point* p,int lo,int mi,int hi){point* A=p+lo;int lenB=mi-lo;//p[lo,mi)int lenC=hi-mi;//p[mi,hi)point* B=new point[lenB];for(int i=0;i<lenB;i++){B[i]=A[i];}point* C=p+mi;for(int i=0,j=0,k=0;i<lenB;){if(j>=lenC||B[i].x<=C[j].x)A[k++]=B[i++];if(j< lenC&&C[j].x< B[i].x)A[k++]=C[j++];}delete[] B;
}void MergeSort_Y(int* p,int lo,int hi){if(hi-lo<2)return;int mi=(lo+hi)/2;MergeSort_Y(p,lo,mi);MergeSort_Y(p,mi,hi);Merge_Y(p,lo,mi,hi);
}void Merge_Y(int* p,int lo,int mi,int hi){int* A=p+lo;int lenB=mi-lo;int lenC=hi-mi;int* B=new int[lenB];int* C=p+mi;for(int i=0;i<lenB;i++){B[i]=A[i];}for(int i=0,j=0,k=0;i<lenB;){if(j>=lenC||B[i]<C[j]){A[k++]=B[i++];if(j<lenC)count+=(lenC-j);//順序對在這里出現}if(j< lenC&&C[j]<=B[i]){A[k++]=C[j++];//這里其實是逆序對}}delete[] B;
}

轉載于:https://www.cnblogs.com/cbw052/p/10467246.html

總結

以上是生活随笔為你收集整理的LightHouse/归并排序的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。