百炼OJ1007

来源:互联网 发布:上海大数据公司 编辑:程序博客网 时间:2024/04/30 03:43

描述
现在有一些长度相等的DNA串(只由ACGT四个字母组成),请将它们按照逆序对的数量多少排序。
逆序对指的是字符串A中的两个字符A[i]、A[j],具有i < j 且 A[i] > A[j] 的性质。如字符串”ATCG“中,T和C是一个逆序对,T和G是另一个逆序对,这个字符串的逆序对数为2。


输入
第1行:两个整数n和m,n(0<n<=50)表示字符串长度,m(0<m<=100)表示字符串数量

第2至m+1行:每行是一个长度为n的字符串
输出
按逆序对数从少到多输出字符串,逆序对数一样多的字符串按照输入的顺序输出。
样例输入
10 6AACATGAAGGTTTTGGCCAATTTGGCCAAAGATCAGATTTCCCGGGGGGAATCGATGCAT
样例输出
CCCGGGGGGAAACATGAAGGGATCAGATTTATCGATGCATTTTTGGCCAATTTGGCCAAA
这个题目意思很简单,关键在于怎么求一个串的逆序数。网上提供的算法多是O(n²),我想了一个O(n)的算法。不过在oj上的运行时间并无太大区别

为了方便运算我用0123代替ACGT,例如CCCGGGGGGA就是1112222220.然后进行如下运算

1 统计一个串中0123出现次数,用t[4]记录。(需要遍历一次)

2 int变量number用来记录逆序数。再次对字符串进行遍历,如果遇到0则number不变,如果遇到1则number=number+t[0],如果遇到2则number=number+t[0]+t[1],

   如果遇到3则number=number+t[0]+t[1]+t[3]。假设遇到的数字是a则t[a]--;

3 按照题目要求排序

import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int l = sc.nextInt();int n = sc.nextInt();int total[] = new int[n];String s = null;String array[] = new String[n];for (int i = 0; i < n; i++) {s = sc.next();array[i] = s;int a[] = new int[l];int t[] = new int[4];int number = 0;for (int j = 0; j < l; j++) {a[j] = f(s.substring(j, j + 1));t[a[j]]++;}for (int j = 0; j < l; j++) {if (a[j] != 0) {switch (a[j]) {case 1:number = number + t[0];break;case 2:number = number + t[0] + t[1];break;case 3:number = number + t[0] + t[1] + t[2];break;}}t[a[j]]--;}total[i] = number;}int flag = 0;int index = 0;for (int i = 0; i < n; i++) {flag = Integer.MAX_VALUE;index = 0;for (int j = 0; j < n; j++) {if (total[j] < flag) {flag = total[j];index = j;}}System.out.println(array[index]);total[index] = Integer.MAX_VALUE;}}public static int f(String s) {if (s.equals("A"))return 0;else if (s.equals("C"))return 1;else if (s.equals("G"))return 2;elsereturn 3;}}


0 0
原创粉丝点击