列表

详情


NC53632. 排序

描述

小a有一个DNA序列串,强迫症的小a看它不顺眼,想将它排好序。
给定长为n的DNA序列串s(仅由`A,T,G,C`最多四种字符构成)。你可以进行任意次如下操作:任选两个位置i,j(),交换这两个字符s_i,s_j,花费为(即:s_i不断与交换,直到移动到j位置,再将s_j不断与交换,直到移动到i位置所需的总移动次数)。求将序列串中同种字符划分到一起的最小花费(如字符串`AGACG`,将其变成`AAGGC`或`GGAAC`或`CAAGG`...都是合法的,最小花费是2:`AAGGC`)。

输入描述

输入一行,一个字符串s,表示题目描述所述的DNA序列串。

输出描述

输出一个整数,表示将s中同种字符划分到一起的最小花费。

示例1

输入:

AGACG

输出:

2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 65ms, 内存消耗: 620K, 提交时间: 2020-03-18 15:47:10

#include<bits/stdc++.h>
using namespace std;

char R[200005],T[4]={'A','C','G','T'};
long long i,ans=2e18,s,a,b,c;
int main()
{
	scanf("%s",R);
	do
	{
        for(a=b=c=s=i=0;R[i]!='\0';i++)
		{
            if(R[i]==T[3]||R[i]==T[2]||R[i]==T[1])a++;
            if(R[i]==T[3]||R[i]==T[2])b++;
            if(R[i]==T[3])c++;
            if(R[i]==T[0])s+=a;
            if(R[i]==T[1])s+=b;
            if(R[i]==T[2])s+=c;
        }
        ans=min(ans,s);
    }while(next_permutation(T,T+4));
	printf("%lld\n",ans);
}

C++14(g++5.4) 解法, 执行用时: 120ms, 内存消耗: 8648K, 提交时间: 2020-01-13 17:33:26

#include<bits/stdc++.h>
using namespace std;
char s[200010];
map<char,int> mmp;
int flag[2000010];
int main(){
	scanf("%s",s+1);
	int n=strlen(s+1);
	int a[]={0,1,2,3,4};
	long long Min=LONG_LONG_MAX;
	while(next_permutation(a+1,a+4+1)){
		memset(flag,0,sizeof flag);
		mmp['A']=a[1],mmp['T']=a[2],mmp['G']=a[3],mmp['C']=a[4];
		long long ans=0;
		for(int i=1;i<=n;++i){
			for(int j=mmp[s[i]]+1;j<=4;++j){
				ans+=flag[j];
			}
			flag[mmp[s[i]]]++;
		}
		Min=min(ans,Min);
	}
	cout<<Min<<endl;
	return 0;
}

上一题