题目大意:给定多个ACGT序列,按照字母顺序算出逆序数,按逆序数从小到大排列
这题其实很简单,我们只要用一个归并排序算逆序数,然后快排就可以了(插入排序也可以,数据量不大),但是要注意的是他要保持原来的顺序,fcmop那里要写当a.inverse=b.inverse时,返回0
1 #include <iostream> 2 #include <functional> 3 #include <algorithm> 4 5 using namespace std; 6 typedef int Position; 7 typedef struct _set 8 { 9 char input[51]; 10 int inverse; 11 }Set; 12 13 void Merge_Sort(Position, Position, int *const); 14 void Merge(Position, Position, int *const); 15 16 static Set input[105]; 17 static char A[53], Tmp_Array[53]; 18 19 int fcomp(const void *a, const void *b) 20 { 21 if ((*(Set *)a).inverse - (*(Set *)b).inverse == 0) 22 return 0; 23 return (*(Set *)a).inverse - (*(Set *)b).inverse; 24 } 25 26 int main(void) 27 { 28 int line_sum, length, inverse_num; 29 30 while (~scanf("%d%d", &length, &line_sum)) 31 { 32 getchar(); 33 for (int i = 0; i < line_sum; i++) 34 { 35 scanf("%s", input[i].input); 36 strcpy(A, input[i].input); 37 inverse_num = 0; 38 Merge_Sort(0, length - 1, &inverse_num); 39 input[i].inverse = inverse_num; 40 } 41 qsort(input, line_sum, sizeof(Set), fcomp); 42 for (int i = 0; i < line_sum; i++) 43 printf("%s ", input[i].input); 44 } 45 return 0; 46 } 47 48 void Merge_Sort(Position Left, Position Right, int *const Inverse_Num) 49 { 50 if (Left < Right) 51 { 52 Position Mid = (Left + Right) / 2; 53 Merge_Sort(Left, Mid, Inverse_Num); 54 Merge_Sort(Mid + 1, Right, Inverse_Num); 55 Merge(Left, Right, Inverse_Num); 56 } 57 } 58 59 void Merge(Position Left, Position Right, int *const Inverse_Num) 60 { 61 Position Mid = (Left + Right) / 2, lpos = Left, rpos = Mid + 1, pos = Left; 62 63 for (; lpos <= Mid && rpos <= Right;) 64 { 65 if (A[lpos] <= A[rpos]) 66 Tmp_Array[pos++] = A[lpos++]; 67 else 68 { 69 Tmp_Array[pos++] = A[rpos++]; 70 (*Inverse_Num) += (Mid + 1 - lpos); 71 } 72 } 73 while (lpos <= Mid) 74 Tmp_Array[pos++] = A[lpos++]; 75 while (rpos <= Right) 76 Tmp_Array[pos++] = A[rpos++]; 77 for (int i = Left; i <= Right; i++) 78 A[i] = Tmp_Array[i]; 79 }