题目大意:对字符串数组按照逆序数数量进行排序。
题目链接:http://poj.org/problem?id=1007
首先统计每个字符串的逆序数数量,这里采用(n*logn)时间复杂度的二路归并方法(此题n^2复杂度方法貌似也不会超时;鉴于此题字符串只有ATCG四个字母,也可以分别统计每个字母出现次数的前缀和,再一次遍历统计逆序数),然后根据逆序数快排即可。
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
#define MAXN 105
struct Entry{
char str[MAXN];
int w;
};
Entry a[MAXN];
char s[MAXN];
char tmp[MAXN];
int merge(char* s,int low,int mid,int high)
{
int i=low;
int j=mid+1;
int k=low;
int count=0;
while(i<=mid&&j<=high)
{
if(s[i]<=s[j])
tmp[k++]=s[i++];
else
{
tmp[k++]=s[j++];
count+=j-k;
}
}
while(i<=mid)
tmp[k++]=s[i++];
while(j<=high)
tmp[k++]=s[j++];
for(i=low;i<=high;i++)
s[i]=tmp[i];
return count;
}
int mergeSort(char* s,int a,int b)
{
if(a<b)
{
int mid=(a+b)/2;
int count=0;
count+=mergeSort(s,a,mid);
count+=mergeSort(s,mid+1,b);
count+=merge(s,a,mid,b);
return count;
}
else return 0;
}
bool cmp(Entry a,Entry b)
{
return a.w<b.w;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i=0;i<m;i++)
{
scanf("%s",a[i].str);
strcpy(s,a[i].str);
a[i].w=mergeSort(s,0,n-1);
}
sort(a,a+m,cmp);
for(int i=0;i<m;i++)
{
printf("%s\n",a[i].str);
}
}
return 0;
}