Pagini recente » Cod sursa (job #1394766) | Cod sursa (job #66914) | Cod sursa (job #2023082) | Cod sursa (job #1649652) | Cod sursa (job #2740396)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("adn.in");
ofstream fout("adn.out");
typedef unsigned long long ull;
typedef long long ll;
int n;
vector<string> s,aux;
ull h[51][30005],pw[30005];
const ull baza=5;
string ans;
vector<int> muchii[51];
string lft[51];
bool use[51];
ll cost[51][51];
int dp[270005][21],from[270005][21];
bool comp(string a, string b)
{
if(a.size()!=b.size())
return a.size()<b.size();
return a<b;
}
void dfs(int nod)
{
use[nod]=1;
bool first=1;
ans+=lft[nod];
for(auto i:muchii[nod])
if(!use[i])
{
if(!first)
{
first=0;
}
else
ans+=s[nod];
dfs(i);
}
}
ull toint(char c)
{
if(c=='A')
return 1;
if(c=='C')
return 2;
if(c=='G')
return 3;
if(c=='T')
return 4;
}
bool common(int i, int j)
{
int lgi=s[i].size();
int lgj=s[j].size();
for(int dr=lgi-1;dr<lgj;dr++)
{
ull hs=h[j][dr];
ll st=dr-lgi;
if(st>=0)
hs-=h[j][st]*pw[lgi];
if(hs==h[i][lgi-1])
return 1;
}
return 0;
}
string getpref(int i, int j)
{
string ans;
int maxi=0;
for(int dr=0;dr<s[j].size();dr++)
{
ull hj=h[j][dr];
ull st=s[i].size()-1-dr;
if(st<0)
break;
ull hi=h[i][s[i].size()-1];
if(st>0)
hi-=h[i][st-1]*pw[dr+1];
if(hi==hj)
maxi=dr+1;
}
ans=s[j].substr(0,maxi);
return ans;
}
int main()
{
fin>>n;
pw[0]=1;
for(int i=1;i<=30000;i++)
pw[i]=pw[i-1]*baza;
for(int i=1;i<=n;i++)
{
string a;
fin>>a;
s.push_back(a);
}
sort(s.begin(),s.end());
s.erase(unique(s.begin(),s.end()),s.end());
sort(s.begin(),s.end(),comp);
for(int i=0;i<n;i++)
{
for(int j=0;j<s[i].size();j++)
{
if(j==0)
h[i][j]=toint(s[i][j]);
else
h[i][j]=h[i][j-1]*baza+toint(s[i][j]);
}
for(int j=i-1;j>=0;j--)
if(common(j,i))
use[j]=1;
}
for(int i=0;i<n;i++)
if(!use[i])
aux.push_back(s[i]);
s=aux;
aux.clear();
int suma=0;
for(int i=0;i<s.size();i++)
for(int j=0;j<s[i].size();j++)
{
if(j==0)
h[i][j]=toint(s[i][j]);
else
h[i][j]=h[i][j-1]*baza+toint(s[i][j]);
}
for(int i=0;i<s.size();i++)
{
suma+=s[i].size();
for(int j=0;j<s.size();j++)
if(i!=j)
cost[i][j]=getpref(i,j).size();
}
int lg=s.size();
for(int mask=0;mask<(1<<lg);mask++)
{
int nrbit=0;
for(int bit=0;bit<lg;bit++)
if((mask>>bit)&1)
nrbit++;
if(nrbit==1)
continue;
for(int i=0;i<lg;i++)
if((mask>>i)&1)
for(int j=0;j<lg;j++)
if(i!=j)
if((mask>>j)&1)
if(dp[mask][i]<dp[mask-(1<<i)][j]+cost[j][i])
{
dp[mask][i]=dp[mask-(1<<i)][j]+cost[j][i];
from[mask][i]=j;
}
}
int maxim=0,last;
for(int i=0;i<lg;i++)
if(dp[(1<<lg)-1][i]>maxim)
{
maxim=dp[(1<<lg)-1][i];
last=i;
}
vector<int> order;
order.push_back(last);
int mask=(1<<lg)-1;
while(mask>0)
{
int plsno=last;
last=from[mask][last];
mask-=(1<<plsno);
if(mask!=0)
order.push_back(last);
}
reverse(order.begin(),order.end());
ans+=s[order[0]];
for(int i=1;i<order.size();i++)
{
int cur=order[i],prv=order[i-1];
int sz=getpref(prv,cur).size();
string add=s[cur].substr(sz);
ans+=add;
}
fout<<ans;
return 0;
}