代码长度限制 16 KB
时间限制 400 ms
内存限制 64 MB
题目描述
在一个字符串中逆序数是在该串中与次序相反的字
符对的数目。例如,字母序列 “DAABEC” 的逆序数
是 5 ,因为 D 比它右边的 4 个字母大,而 E 比它右边
的 1 个字母大。序列 “AACEDGG” 的逆序数是 1 ( E 和
D ),几乎已经排好序了。而序列 “ZWQM” 的逆序
数是 6 ,完全没有排好序。
您要对 DNA 字符串序列进行分类(序列仅包含 4 个
字母 A , C , G 和 T )。然而,分类不是按字母顺序,
而是按 “ 排序 ” 的次序,从 “ 最多已排序 ” 到 “ 最少已
排序 ” 进行排列。所有的字符串长度相同。
输入格式
第一行是两个正整数: n ( 0<n≤50 )给出字符串的长度, m( 0<m≤100 )给出字符串的数目。后面是 m 行,每行为长度为 n 的
字符串。
输出格式
对输入字符串按从 “ 最多已排序 ” 到 “ 最少已排序 ” 输出一个列表。两个字符串排序情况相同,则按原来的次序输出。
输入样例
10 6
AACATGAAGG
TTTTGGCCAA
TTTGGCCAAA
GATCAGATTT
CCCGGGGGGA
ATCGATGCAT
输出样例
CCCGGGGGGA
AACATGAAGG
GATCAGATTT
ATCGATGCAT
TTTTGGCCAA
TTTGGCCAAA
个人思路
- 根据描述,只需要倒序遍历判断找出在它右边的字符中比它小的个数并进行累加就可以得出当前字符串的逆序数
- 选择倒序是因为可以用一个长度为四的数组来记录某一个字符是否已出现,方便对每个字符做判断右边比它小的字符数
- 因为输入序列里只包含四个字符,所以可以进行逐个判断,用数组进行for或者用switch()甚至四个if也不会有特别大的代码量及时空复杂度的差异,后面两个无非多了复制粘贴的几下 \笑
#include<bits/stdc++.h>
using namespace std;
struct s
{
string str;
int cnt=0;
};
bool cmp(s a,s b)
{
return a.cnt<=b.cnt;
}
int main()
{
int n,m;
cin>>n>>m;
vector<s> vv;
while(m--)
{
string t;
cin>>t;
s ss;
ss.str=t;
int v[4];
memset(v,0,sizeof(v));
for(int i=t.length()-1;i>=0;i--)
{
switch(t[i])
{
case 'A':
{
v[0]++;
break;
}
case 'C':
{
if(v[0])
ss.cnt+=v[0];
v[1]++;
break;
}
case 'G':
{
if(v[0])
ss.cnt+=v[0];
if(v[1])
ss.cnt+=v[1];
v[2]++;
break;
}
case 'T':
{
if(v[0])
ss.cnt+=v[0];
if(v[1])
ss.cnt+=v[1];
if(v[2])
ss.cnt+=v[2];
v[3]++;
}
default:
break;
}
}
vv.push_back(ss);
}
sort(vv.begin(),vv.end(),cmp);
for(int i=0;i<vv.size();i++)
{
cout<<vv[i].str<<endl;
}
}