数据结构1-3 灯塔

我自己用的merge排序,只有50通过。待我优化一下。


#include <iostream>
using namespace std;
#define maxLength  4000000
typedef long long Rank;
class Node{
public:
int x;
int y;
};
class NodeList{
public:
Node* _elem;
int _size;
void copyFrom(Node* A , int lo, int hi);
NodeList(Node *A, int n){copyFrom(A, 0, n);}
NodeList(){_size = 0;_elem = new Node[3];}
Rank invertion(int lo, int mi, int hi);
Rank invertionCount(int lo, int hi );
};
void NodeList::copyFrom(Node * A,int lo, int hi)
{
_size = 0;
_elem = new Node[2 * (hi - lo)];
while(lo < hi)
_elem[_size++] = A[lo++];
}
Rank NodeList::invertion(int lo, int mi, int hi){
Rank CountNum = 0;
Node *A = _elem+ lo;
int leftNum = mi - lo;
Node *B = new Node[leftNum];
for (int i = 0 ; i < leftNum ;B[i] = A[i++]);
int rightNum = hi - mi;
Node *C = _elem + mi;
for (int i = 0, j = 0, k = 0; (k < rightNum) || (j < leftNum);)
{
if ((j < leftNum) && (! (k <  rightNum) || B[j].x <= C[k].x) )
{
for (int tmp = k; tmp < rightNum; tmp++)
{
if (B[j].y < C[tmp].y)
{
CountNum++;
}
}
A[i++] = B[j++];
};


if ( ( k < rightNum ) && (! (j < leftNum) || C[k].x < B[j].x))
{
for (int tmp = j; tmp < leftNum; tmp++)
{
if (C[k].y < B[tmp].y)
{
CountNum++;
}
}
A[i++] = C[k++];
}


}
delete []B;
return CountNum;


}
Rank NodeList::invertionCount(int lo, int hi ){
if (hi - lo  < 2)
return 0;
int mi = (lo + hi) >> 1;
Rank a =invertionCount(lo ,mi);
Rank b =invertionCount(mi, hi);
Rank c =invertion(lo ,mi, hi);
return a + b + c;
}


int main(){
Node  *A = new Node[maxLength];
int n;
cin >> n;


for (int i = 0;i < n ;i++)
{
Node tmp;
cin >> tmp.x >> tmp.y;
A[i] = tmp;
}
NodeList *listA = new NodeList(A,n);
cout << listA->invertionCount(0,n);


}

//参考网上的思路,先用快排对x坐标进行排序,之后仅对y进行处理,计算逆序对数,之后用(n) * (n -1)/2 - 逆序对数 就是正序对数。过了95%

#include <stdio.h>

#include <stdlib.h>
#define maxLength  4000000
typedef long long Rank;
class Node{
public:
int x;
int y;
};
class NodeList{
public:
int* _elem;
int _size;
void copyFrom(Node* A , int lo, int hi);
NodeList(Node *A, int n){copyFrom(A, 0, n);}
NodeList(){_size = 0;_elem = new int[3];}
Rank invertion(int lo, int mi, int hi);
Rank invertionCount(int lo, int hi );
};
void NodeList::copyFrom(Node * A,int lo, int hi)
{
_size = 0;
_elem = new int[2 * (hi - lo)];
while(lo < hi)
_elem[_size++] = A[lo++].y;
}
Rank NodeList::invertion(int lo, int mi, int hi){
Rank CountNum = 0;
int *A = _elem+ lo;
int leftNum = mi - lo;
int *B = new int[leftNum];
for (int i = 0 ; i < leftNum ;B[i] = A[i++]);
int rightNum = hi - mi;
int *C = _elem + mi;
for (int i = 0, j = 0, k = 0; (k < rightNum) || (j < leftNum);)
{
if ((j < leftNum) && (! (k <  rightNum) || B[j] <= C[k]) )
{
A[i++] = B[j++];
};


if ( ( k < rightNum ) && (! (j < leftNum) || C[k] < B[j]))
{
A[i++] = C[k++];
CountNum += leftNum - j;
}


}
delete []B;
return CountNum;


}
Rank NodeList::invertionCount(int lo, int hi ){
if (hi - lo  < 2)
return 0;
int mi = (lo + hi) >> 1;
Rank a =invertionCount(lo ,mi);
Rank b =invertionCount(mi, hi);
Rank c =invertion(lo ,mi, hi);
return a + b + c;
}
int cmp(const void *a,const void *b)
{
return (*(Node*)a).x > (*(Node*)b).x ? 1 : -1;
}




int main(){
Node  *A = new Node[maxLength];
int n;
scanf("%d", &n);


for (int i = 0;i < n ;i++)
{
Node tmp;
scanf("%d%d",&tmp.x,&tmp.y);
A[i] = tmp;
}
qsort(A,n,sizeof(A[0]),cmp);


NodeList *listA = new NodeList(A,n);
Rank tmp = Rank(n) * Rank(n - 1)/2;
printf("%lld",tmp - listA->invertionCount(0,n) );
}

fread我真的是不太会了.....

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值