數據結構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我真的是不太會了.....

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章