//统计逆序对数,用归并排序来统计 O(nlgn) 应该比枚举要快,不过在这题中应该不会体现,反而浪费了空间,不过算了,当练归并排序 #include<iostream> #include<algorithm> #define INF 2147483647 using namespace std; struct str { char source[100];//保存原始序列 char s[100]; int misorder; }DNA[101]; int len,n,_min,flag,cnt;//逆序对数 char T[100]; int merge_sort(char A[],int x,int y,char T[])//归并排序 { if(y-x > 1) { int m = (x+y) / 2; int p = x,q = m,i = x; merge_sort(A,x,m,T); merge_sort(A,m,y,T); while(p < m || q < y) { if(q >= y || (p < m && A[p] <= A[q])) T[i++] = A[p++]; else { T[i++] = A[q++]; cnt += m - p;//统计逆序对数 } } for(i = x;i < y;++i) A[i] = T[i]; } return cnt;//返回逆序对数 } int main() { //freopen("in.txt","r",stdin); scanf("%d%d",&len,&n); for(int i = 0;i < n;++i) { scanf("%s",DNA[i].s); strcpy(DNA[i].source,DNA[i].s); cnt = 0; DNA[i].misorder = merge_sort(DNA[i].s,0,len,T); } //一开始我用qsort的结构体排序,以为很方便,结果WA,原因是qsort是不稳定的,当逆序数对相同时,它不能保证结构体中的其他内容仍然按照原始顺序排列 //结果无奈就用了个最脑残的O(n^2)排序…… for(int j = 0;j < n;++j) { _min = INF; for(int i = 0;i < n;++i) { if(DNA[i].misorder < _min) { _min = DNA[i].misorder; flag = i; } } printf("%s/n",DNA[flag].source); DNA[flag].misorder = INF; } return 0; }