基因
Problem Description
Enigma得到了一个基因“ATCC”,他想把它重组为一个新的基因“CTCA”。他可以任意使用下列两种方法:(1) 交换基因的前两个字符; (2) 将第一个字符移到最后。例如:“ATCC”经过方法2重组为“TCCA”,然后“TCCA”经过方法1重组从而得到了“CTCA”。你的任务是写个程序帮助Enigma发现重组基因的最小步骤。
Input
Output
Sample Input
4 ATCC CTCA 4 ATCG GCTA 4 ATCG TAGC 0
Sample Output
2 4 6
关键是hash函数的构建
#include<iostream>
#include<queue>
#include<string>
#define mai 4
#define maxin 369600
using namespace std;
bool visit[369600];
int total,n;
int c[4];
int a[12];
int b[12];
int ss[12];
int temp1,temp2;
int p[8];
void tanslate(int x,int p[])
{
int i;
for(i=n-1;i>=0;i--)
{
p[i]=x%4;
x/=4;
}
}
int fan(char s)
{
if(s=='A') return 0;
else if(s=='T') return 1;
else if(s=='C') return 2;
else if(s=='G') return 3;
}
int lmx(int c[])
{
int i,sum=0;
for(i=0;i<n;i++)
{
sum=sum*mai+c[i];
}
return sum;
}
int ff[4];
int pp[4];
int hash(int *s)
{
int ret=0,sum=total,i,j;
for(i=0;i<4;i++)
{
pp[i]=ff[i];
}
for(i=0;i<n;i++)
{
for(j=0;j<s[i];j++)
{
if(pp[j]) ret+=sum*pp[j]/(n-i);
}
sum=sum*pp[s[i]]/(n-i);
pp[s[i]]--;
}
return ret;
}
void swap(int &x,int &y)
{
int temp=x;
x=y;
y=temp;
}
struct lmxi{
int x;
int step;
};
queue<lmxi>q;
int bfs()
{
int i;
lmxi s1,s2,s3;
while(!q.empty()) q.pop();
s1.x=temp1;
s1.step=0;
if(temp1==temp2) return 0;
tanslate(s1.x,a);
visit[hash(a)]=true;
q.push(s1);
while(!q.empty())
{
s2=q.front();
q.pop();
if(s2.x==temp2) return s2.step;
for(i=0;i<2;i++)
{
tanslate(s2.x,a);
if(i==0)
{
swap(a[0],a[1]);
}
else
{
int j,ts;
ts=a[0];
for(j=0;j<n-1;j++)
{
a[j]=a[j+1];
}
a[n-1]=ts;
}
int sm=hash(a);
if(visit[sm]!=true)
{
int t=lmx(a);
if(t==temp2) return s2.step+1;
else {
visit[sm]=true;s3.step=s2.step+1;s3.x=t;q.push(s3);
}
}
}
}
}
int main()
{
int ca,i;
string s1,s2;
while(cin>>ca)
{
if(ca==0) break;
cin>>s1>>s2;
n=s1.length();
for(i=0;i<s1.length();i++)
{
a[i]=fan(s1[i]);
}
for(i=0;i<s2.length();i++)
{
b[i]=fan(s2[i]);
}
memset(visit,0,sizeof(visit));
temp1=lmx(a);
temp2=lmx(b);
total=1;
memset(c,0,sizeof(c));
memset(ff,0,sizeof(ff));
for(i=0;i<n;i++)
{
c[a[i]]++;
ff[a[i]]++;
total*=(i+1);
}
for(i=0;i<4;i++)
{
if(c[i]==0) continue;
else
{
while(c[i])
{
total/=c[i];
c[i]--;
}
}
}
cout<<bfs()<<endl;
}
return 0;
}