題目: 燈塔LightHouse
簡要描述: 等效成給定n個座標,統計座標軸上兩點x y方向只差是同向的,n點的x y座標不會有重疊.html
思路:
1. 對n點循環遍歷,對兩點作差值,知足y x方向同時大於或小於,那麼累計+1->題目中給定數量級10^6,
時間複雜度太大,O(n!),不可用
2. 先對x方向進行排序,再統計y方向的相對順序,若是y方向的也是順序的,那麼這兩點必然知足條件+1
3. 需進行兩次排序,採用歸併排序將時間複雜度降爲nlogn
, 第一次對x方向上歸併排序,第二次對y
方向上進行歸併排序,同時對順序對計數.數組
假設各級子序列的歸併排序已經完成,只剩下A B兩個區間,那麼能夠保證A中全部元素x都比B中元素小,
合併子序列的時候若是A[i]y方向小於B[j],那麼j及j後全部元素都應該統計爲順序對中.函數
實現
1. 讀入元素後進行兩次歸併排序
2. 歸併排序雙路合併函數中區分出x方向排序和y方向排序,y方向排序同時進行計數
3. 雙路合併函數中若是動態分配存儲空間用於臨時存儲數組,10%超時,改爲全局數組後95%用例經過,
仍有5%不行,瓶頸應該仍是數組for循環的賦值,沒有想到啥辦法.code
代碼htm
cpp#include <stdio.h> struct points { int x; int y; }; // global bool isBeacon(points lighthouse1, points lighthouse2); void merge(int lo, int mi, int hi, int flag=1); void mergeSort(int lo, int hi, int flag=1); int irow = 0; long iTotalNum = 0; points pointsLocate[4000000] = {}; points B[4000000] = {}; void getInputNum() { scanf("%d", &irow); for(int i=0; i<irow; i++) { int temp1, temp2; scanf("%d %d", &temp1, &temp2); pointsLocate[i].x = temp1; pointsLocate[i].y = temp2; } } bool lower_x(points left, points right) { return (left.x < right.x); } bool lower_y(points left, points right) { return (left.y < right.y); } void merge(int lo, int mi, int hi, int flag) { //points *B = new points[mi-lo]; int lb = mi - lo; int j = lo; int i=0; for(; i<lb;) { B[i] = pointsLocate[j]; i++; j++; } int lc = hi-mi; points *A = &pointsLocate[lo]; points *C = &pointsLocate[mi]; if(flag == 1) { for(int i=0, j=0, k=0; j<lb || k<lc;) { if(j<lb && (lc <= k || lower_x(B[j], C[k]))) A[i++] = B[j++]; if(k<lc && (lb <= j || lower_x(C[k], B[j]))) A[i++] = C[k++]; } } else { for(int i=0, j=0, k=0; j<lb || k<lc;) { if(j<lb && (lc <= k || lower_y(B[j], C[k]))) { if(lower_y(B[j], C[k])) { iTotalNum += lc-k; // printf("%d-%d-%d\n", lo, hi, lc-k); } A[i++] = B[j++]; } else if(k<lc && (lb << j || lower_y(C[k], B[j]))) A[i++] = C[k++]; // iTotalNum += lb-j; } } //delete B; } //nlogn void mergeSort(int lo, int hi, int flag) { if(hi - lo < 2) return; int mi = (lo+hi) >> 1; mergeSort(lo, mi, flag); mergeSort(mi, hi, flag); merge(lo, mi, hi, flag); } int main() { #ifndef _OJ_ freopen("inputlight.txt", "r", stdin); #endif getInputNum(); mergeSort(0, irow, 1); mergeSort(0, irow, 2); printf("%ld\n", iTotalNum); return 0; } //n^2複雜度 bool isBeacon(points lighthouse1, points lighthouse2) { if(lighthouse1.x>lighthouse2.x && lighthouse1.y>lighthouse2.y) return true; if(lighthouse1.x<lighthouse2.x && lighthouse1.y<lighthouse2.y) return true; return false; }