Pagini recente » Cod sursa (job #2299552) | Cod sursa (job #1338938) | Cod sursa (job #1266281) | Cod sursa (job #1372011) | Cod sursa (job #2269224)
#include<fstream>
#include<vector>
#include<string>
#include<algorithm>
#define modulo 666013
#define INF 10000000
using namespace std;
ifstream fin("adn.in");
ofstream fout("adn.out");
const int NMAX = 19;
string sir;
int i, n, k, j,contor,st,dr,x,y;
string word[NMAX], words[NMAX];
int d[1 << NMAX][NMAX];
int last[1 << NMAX][NMAX];
int aux[NMAX][NMAX];
int included[30100];
int prefix[NMAX][30100];
int w[NMAX], lung[NMAX];
bool cmp(string a, string b)
{
return a.size() < b.size();
}
void generatePrefix(string& b, int x)
{
prefix[x][1] = 0;
int k = 0;
for(int i = 2; i < b.size(); i++)
{
while(k > 0 && b[k + 1] != b[i])
{
k = prefix[x][k];
}
if(b[k + 1] == b[i])
{
k++;
}
prefix[x][i] = k;
}
}
int getPrefix(string& a, string &b,int x, int y)
{
k = 0;
for(int i = 1; i < a.size(); i++)
{
while(k > 0 && b[k + 1] != a[i])
{
k = prefix[y][k];
}
if(b[k + 1] == a[i])
{
k++;
}
if(k == b.size() - 1)
{
included[y] = 1;
k = prefix[y][k];
}
}
aux[x][y] = k;
}
int main()
{
fin >> n;
for(i = 0; i < n; i++)
{
fin >> word[i];
lung[i] = word[i].size();
word[i] = ' ' + word[i];
generatePrefix(word[i], i);
}
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
///cel mai lung sufix al lui i care este prefix al lui j
if(i != j)
{
getPrefix(word[i], word[j], i, j);
}
}
}
int newN = 0;
for(i = 0; i < n; i++)
{
if(included[i] == 0)
{
w[newN] = i;
newN++;
}
}
//fout << newN <<"\n";
n = newN;
for(i = 0; i < n; i++)
{
d[(1 << i)][i] = lung[w[i]];
last[(1 << i)][i] = -1;
}
for(int stare = 1; stare < 1 << n; stare++)
{
for(i = 0; i < n; i++)
{
if(d[stare][i] != 0)
{
for(j = 0; j <n; j++)
{
if(i != j && ((stare & (1 << j) )== 0))
{
int lPrefix = aux[w[i]][w[j]];
int value = lung[w[j]] - aux[w[i]][w[j]];
if(d[(stare + (1 << j))][j] == 0 || d[(stare + (1 << j))][j] > d[stare][i] + value)
{
d[(stare + (1 << j))][j] = d[stare][i] + value;
last[(stare + (1 << j))][j] = i;
}
}
}
}
}
}
int minim = INF;
int pos = -1;
for(i = 0; i < n; i++)
{
if(minim > d[(1 << n) - 1][i])
{
minim = d[(1 << n) - 1][i];
pos = i;
}
}
int stare = (1 << n) - 1;
string sol = "";
while(last[stare][pos] != -1)
{
int newPos = last[stare][pos];
int nr = aux[w[newPos]][w[pos]];
string aux = "";
for(i = nr+1; i <= lung[w[pos]]; i++)
{
aux = aux + word[w[pos]][i];
}
sol = aux + sol;
stare = stare - (1 << pos);
pos = newPos;
}
sol = word[w[pos]] + sol;
sol.erase(0, 1);
fout << sol << "\n";
}