poj1007--DNA Sorting解题报告

题目要求的是一条DNA序列的逆序数,求逆序数可以考虑使用归并算法来进行求解。

我们来设想这样一个场景:相邻的A、B两块进行升序排序,各自都已经是排好序的了,且B排在A右边。那么当把B中的某数T放到已排序的数列中,那么A序列中剩下的数就是比数T要大的,但我们要注意到:在原序列中,由于B序列在A序列右边,那么对于“AB”块中,与数T对应的逆序数就是A序列中剩下的数量。

这便是用归并算法计算逆序数的精髓所在。

一个乱序序列的 逆序数 = 在只允许相邻两个元素交换的条件下,得到有序序列的交换次数


#include<iostream>
#include<algorithm>
using namespace std;

int number = 0;
typedef class dna  
{  
    public:  
        int num;  //逆序数  
        char sq[110];  //DNA序列  
		string sq_bankend;
}DNAStr; 

void Merge(char* r,char* r1,int s,int m, int t)
{
	int i = s;
	int j = m+1;
	int k = s;
	while(i<=m && j<=t)
	{
		if(r[i] <= r[j] )
			r1[k++] = r[i++];
		else 
			{
				number += m-i+1; //用来统计逆序数
				r1[k++] = r[j++];
			}
	} 

	if( i<=m)
		while(i<=m)
			r1[k++] = r[i++];
	else
		while(j<=t)
			r1[k++] = r[j++];	
	return;
}


void MergePass(char* r,char* r1,int n,int h)
{
    int i=0;  
    int k;  
  
	while(i<=n-2*h)
	{
		Merge(r,r1,i,i+h-1,i+2*h-1);
		i += 2*h;
	}

	if(i<n-h) Merge(r,r1,i,i+h-1,n-1);
	else 
		for(k = i;k<n;k++)
			r1[k] = r[k];
}

int MergeSort(char* r ,int n)
{
	int h =1;
	char *r1 = (char*)malloc(sizeof(char) * n);  
	while(h<n)
	{
		MergePass(r,r1,n,h);
		h = 2*h;
		MergePass(r1,r,n,h);
		h = 2*h;
	}
	free(r1);
	return number;
}

int cmp(const void* a,const void* b)  
{  
    DNAStr* x=(DNAStr*)a;  
    DNAStr* y=(DNAStr*)b;  
    return (x->num)-(y->num);  
}  

int main()
{
	int n,m;  
    while(cin>>n>>m)  
    {  
        DNAStr* DNA=new DNAStr[m];  
        for(int i=0;i<m;i++)  
        {  
			cin>>DNA[i].sq;
			DNA[i].sq_bankend = DNA[i].sq;
            DNA[i].num = MergeSort(DNA[i].sq,n);  
			number = 0;
        }  
        qsort(DNA,m,sizeof(DNAStr),cmp);  
        for(int j=0;j<m;j++)  
			cout<<DNA[j].sq_bankend.c_str()<<endl;  
    }
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值