[OJ]_LightHouse实现

题目: 灯塔LightHouse
简要描述: 等效成给定n个坐标,统计坐标轴上两点x y方向只差是同向的,n点的x y坐标不会有重叠.

思路:
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循环的赋值,没有想到啥办法.

代码

cpp#include  
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> 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

你可能感兴趣的:(数据结构,c++,归并排序)