Pagini recente » Cod sursa (job #1854408) | Profil IulianOleniuc | Cod sursa (job #622158) | Cod sursa (job #827104) | Cod sursa (job #693663)
Cod sursa(job #693663)
#include <fstream>
#include <string>
#define INF 0x3f3f3f3f
using namespace std;
int pi[30005], graph[18][18], st, C[(1 << 18)][18], before[(1 << 18)][18];
bool not_show[18];
string adn[18];
bool not_included(int i, int j)
{
if(adn[i].size() > adn[j].size())
return true;
int j_pos = 0, i_pos = 0;
while(j_pos+i_pos < adn[i].size())
{
if(adn[i][i_pos] == adn[j][j_pos+i_pos])
{
if(i_pos == adn[i].size()-1)
{
not_show[i] = true;
return false;
}
else
++i_pos;
}
else
{
j_pos = j_pos + i_pos - pi[i_pos];
if(pi[i]>-1)
i = pi[i];
else
i = 0;
}
}
return true;
}
int main()
{
int n;
ifstream in("adn.in");
in >> n;
for(int i = 0; i < n; ++i) in >> adn[i];
in.close();
for(int i = 0; i < n; ++i) //Pi function
{
int w_size = adn[i].size();
int back = 0, pos = w_size-3;
pi[w_size-1] = -1;
pi[w_size-2] = 0;
while (pos >= 0)
{
if(adn[i][pos+1] == adn[i][w_size-back-1])
{
++back;
pi[pos] = back;
--pos;
}
else
if(back > 0)
back = pi[w_size-back-1];
else
{
pi[pos] = 0;
--pos;
}
}
for(int j = 0; j < n; ++j) //Make graph
{
if(i!=j&&(!not_show[i]))
{
int now = 0, pos = 0, w_size = adn[i].size(), s_size = adn[j].size();
while (now < s_size)
{
if(((adn[i][w_size-1-pos] == adn[j][s_size-1-(now+pos)])&&(now+pos < s_size))||(now+pos >= s_size))
{
if(pos == w_size-1)
{
if(now+pos < s_size)
{
not_show[i] = true;
break;
}
graph[i][j] = s_size - now;
break;
}
else
++pos;
}
else
{
now = now + pos - pi[w_size-1-pos];
if(pi[w_size-1-pos] > -1)
pos = pi[w_size-1-pos];
else
pos = 0;
}
}
}
}
}
for(int i = 0; i < (1<<n); ++i)
for(int j = 0; j < n; ++j)
C[i][j] = INF;
for(int i = 0; i < n; ++i)
C[1<<i][i] = 0;
for(int i = 1; i < (1<<n); ++i)
{
for(int j = 0; j < n; ++j)
{
if(i&(1<<j))
for(int k = 0; k < n; ++k)
{
if((C[i][j] == INF && C[i^(1<<j)][k] != INF) || (C[i^(1<<j)][k] != INF && C[i^(1<<j)][k] + graph[j][k] > C[i][j]))
{
C[i][j] = C[i^(1<<j)][k] + graph[k][j];
before[i][j] = k;
}
}
}
}
int i = (1<<n)-1, max = -1, sj = 0, prev = -1, tmp;
for(int j = 0; j < n; ++j)
if(C[i][j] > max && C[i][j] != INF)
{
max = C[i][j];
sj = j;
}
ofstream out("adn.out");
for(int j = 0; j < n; ++j)
{
if(!not_show[sj])
{
for(int k = graph[prev][sj]; k < adn[sj].size(); ++k)
out << adn[sj][k];
}
tmp = sj;
sj = before[i][tmp];
i = i ^ (1<<tmp);
prev = tmp;
}
out.close();
return 0;
}