[OJ]_LightHouse實現

題目: 燈塔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;
}
相關文章
相關標籤/搜索