poj 4086:DNA排序

poj 4086:DNA排序

题目

描述

现在有一些长度相等的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 6
AACATGAAGG
TTTTGGCCAA
TTTGGCCAAA
GATCAGATTT
CCCGGGGGGA
ATCGATGCAT
样例输出
CCCGGGGGGA
AACATGAAGG
GATCAGATTT
ATCGATGCAT
TTTTGGCCAA
TTTGGCCAAA

解题思路

我们主要解决的问题是找出一个字符串的逆序对

针对此我设计一下数据结构

dna hashtable 每一元素记录对应map中value-key中key出现的次数,此表是不断更新中的

好了我的算法思路用代码呈现吧

#include <iostream>
#include <map>
#include <fstream>
#include <algorithm>
#include <string>
using namespace std;

class Elem
{
public:
	int num;
	int order;
	string dna;
};

bool compare(Elem  a,Elem  b)
{
	if(a.num < b.num)
		return true;
	else if( a.num == b.num && a.order < b.order )
		return true;
	else return false;
}

map<char,int> dnamap;
const int dna_length = 4;

void main_solution();
void read_data(string* & data,int &m);
int inversion( string & dna );
void initialize_map(map<char,int> &dnamap);

int main( )
{
	main_solution();
	system( "pause" );
	return 0;
}

void initialize_map(map<char,int> &dnamap)
{
	dnamap.insert( make_pair('A',0) );
	dnamap.insert( make_pair('C',1) );
	dnamap.insert( make_pair('G',2) );
	dnamap.insert( make_pair('T',3) );
}

// 求出dna字符串的逆序对
int inversion( string & dna )
{
	int num = 0;
	int now;
	int * dnahash = new int[ dna_length ];
	for(int i=0;i<dna_length;i++)
	{
		dnahash[i] = 0;
	}

	for( int i=0;i<dna.length();i++ )
	{
		now = dnamap.find( dna[i] )->second;
		dnahash[ now ] ++;
		for( int j = now+1; j<dna_length; j++ )
		{
			num += dnahash[j];
		}
	}
	return num ;
}

void read_data(string* & data,int &m)
{
	ifstream reader;
	reader.open("data.txt");
	reader>>m;
	reader>>m;
	data = new string[m];

	for( int i =0; i<m; i++ )
	{
		reader>>data[i];
	}
	reader.close();
}

void main_solution()
{
	string * data;
	int m;
	read_data(data,m);
	initialize_map(dnamap);
	Elem * myset = new Elem[m];
	for(int i=0;i<m;i++)
	{
		myset[i].dna = data[i];
		myset[i].order = i;
		myset[i].num = inversion(data[i]);
	}

	sort(myset,myset+m,compare);

	for(int i=0;i<m;i++)
		cout<<myset[i].dna<<endl;
}

时间: 2024-08-29 06:22:20

poj 4086:DNA排序的相关文章

POJ 1007:DNA排序

AC CODE: 1 import java.util.Scanner; 2 3 public class Main { 4 5 public static void main(String[] args) { 6 Scanner input = new Scanner(System.in); 7 8 // 得到数据 9 int n = input.nextInt(); 10 int m = input.nextInt(); 11 String temp = input.nextLine();

poj 4084:拓扑排序

poj 4084:拓扑排序 很好的题目,恶心的算法 描述 给出一个图的结构,输出其拓扑排序序列,要求在同等条件下,编号小的顶点在前. 输入 若干行整数,第一行有2个数,分别为顶点数v和弧数a,接下来有a行,每一行有2个数,分别是该条弧所关联的两个顶点编号. v<=100, a<=500 输出 若干个空格隔开的顶点构成的序列(用小写字母). 样例输入 6 8 1 2 1 3 1 4 3 2 3 5 4 5 6 4 6 5 样例输出 v1 v3 v2 v6 v4 v5 解题方案 显然这是有向图,然

poj 2778 DNA Sequence(AC自动机+矩阵快速幂)

题目链接:poj 2778 DNA Sequence 题目大意:给定一些含有疾病的DNA序列,现在给定DNA长度,问有多少种不同的DNA序列是健康的. 解题思路:对DNA片段建立AC自动机,因为最多10个串,每个串最长为10,所以最多可能有100个节点,在长度为n时 以每个节点终止的健康字符串个数形成一个状态集,通过AC自动机形成的边可以推导出n+1的状态集,走到单词节点是 非法的,所以同样的我们可以先走到单词节点,但是从单词节点不向后转移.这样可以构造一个矩阵,剩下的就是矩阵 快速幂.注意的一

POJ 3691 DNA repair 基于AC自动机的DP

dp[i][j] 表示长度为 i 的前缀到达第 j 个节点的最小更改数目. 很显然有dp[0][0] = 0; dp[ i ][ j ] = min(dp[ i ][ j ],dp[i-1][k] + (j == k ? 0 : 1)),当且仅当j,k满足下列条件时. j 不为某条模式串的末节点 且 j 到 root 的由失败指针组成的路径上无末节点. j 是k的儿子节点 或者 j 的父节点可由 k 沿着失败指针找到. #include <algorithm> #include <ios

[poj 3691]DNA repair

好久没刷 poj 了,今天练习 AC 自动机时去水了一发喵~ 在 poj 上 A 题的感觉并没有 BZOJ 上那么愉悦,准确的说是痛不欲生 真是应了那句老话,你再慢也有比你慢的,你再快也有比你快的…… 跪求那些 0ms 的代码啊,还有那么多人都只跑了 32ms 啊!! 果然还是我太弱了吗?一定是我还太弱了 TAT 一道裸裸的 AC 自动机上 dp 令 dp[i][j] 表示母串的前 i 个字母遍历 AC 自动机,使之到达 j 节点,至少要修改多少个字母 dp[i+1][k]=min(dp[i+1

Poj 1094 拓扑排序 水题

Sad..这么水的题WA了无数发,题目要看仔细啊,留下来做个警告把 #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #i

POJ POJ 2778 DNA Sequence AC自动机 + 矩阵快速幂

首先建立Trie和失败指针,然后你会发现对于每个节点 i 匹配AGCT时只有以下几种情况: i 节点有关于当前字符的儿子节点 j 且安全,则i 到 j找到一条长度为 1的路. i 节点有关于当前字符的儿子节点 j 且 不安全,则i 到 j没有路. i 节点没有关于当前字符的儿子节点 但是能通过失败指针找到一个安全的节点j,那么 i 到 j 找到一条长度为1的路. 关于节点安全的定义: 当前节点不是末节点且当前节点由失败指针指回跟节点的路径上不存在不安全节点,那么这个节点就是安全节点. 然后问题就

Openjudge-计算概论(A)-DNA排序

描述: 给出一系列基因序列,由A,C,G,T四种字符组成.对于每一个序列,定义其逆序对如下: 序列中任意一对字符X和Y,若Y在X的右边(不一定相邻)且Y < X,则称X和Y为一个逆序对. 例如GAC这个序列,其中GC,GA都是逆序对. 一个序列的逆序对越多,则认为其"无序度"越高.你的任务是将基因按照无序度从小到大的顺序排序,如果存在无序度相同的序列,则按照原始输入顺序输出. 输入首先是基因序列的长度n(0 < n <= 50)和基因序列的个数m ( 0 < m

poj 1007 DNA Sorting (求逆序数)

DNA Sorting Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 83069   Accepted: 33428 Description One measure of ``unsortedness'' in a sequence is the number of pairs of entries that are out of order with respect to each other. For instanc