Pagini recente » Cod sursa (job #60048) | Cod sursa (job #1214496) | Cod sursa (job #426462) | Cod sursa (job #2598538) | Cod sursa (job #1979303)
#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[30100];
int w[NMAX], lung[NMAX];
bool cmp(string a, string b)
{
return a.size() < b.size();
}
void init()
{
for(i = 0; i < 1 << n; i++)
{
for(j = 0; j <= NMAX; j++)
{
d[i][j] = 1000000000;
}
}
}
int getPrefix(string& a, string &b,int x, int y)
{
prefix[1] = 0;
int k = 0;
for(int i = 2; i < b.size(); i++)
{
while(k > 0 && b[k + 1] != b[i])
{
k = prefix[k];
}
if(b[k + 1] == b[i])
{
k++;
}
prefix[i] = k;
}
k = 0;
for(int i = 1; i < a.size(); i++)
{
//fout << a[i];
while(k > 0 && b[k + 1] != a[i])
{
k = prefix[k];
}
if(b[k + 1] == a[i])
{
k++;
}
if(k == b.size() - 1)
{
//fout << "intra\n";
included[y] = 1;
//sol.push_back(i - n);
k = prefix[k];
}
}
//fout <<"\n";
//fout << k <<"\n";
//fout << a <<" "<<b << " " << k <<"\n";
aux[x][y] = k;
//fout << k <<"\n"
/* fout << b <<"\n";
for(i = 1; i < b.size(); i++)
{
fout << prefix[i] << " ";
}
fout <<"\n";*/
//fout <<"\n";
}
int main()
{
fin >> n;
init();
for(i = 0; i < n; i++)
{
fin >> word[i];
lung[i] = word[i].size();
word[i] = ' ' + word[i];
//fout << word[i] << "\n";
}
//sort(word + 1, word + n + 1, cmp);
init();
/*for(i = 1; i <= n; i++)
{
for(j = 1; j <= n; j++)
{
if(i != j)
{
fout << word[i] << " " << word[j] <<"\n";
}
}
}*/
for(int i = 0; i < n; i++)
{
//fout << word[i] << "\n";
for(int j = 0; j < n; j++)
{
///cel mai lung sufix al lui i care este prefix al lui j
//aux[i][j] = getPrefix(word[i], word[j]);
//fout <<i <<" "<<j <"\n";
if(i != j)
{
getPrefix(word[i], word[j], i, j);
//fout << i <<" "<<j <<" " <<aux[i][j]<<"\n";
}
}
}
int newN = 0;
for(i = 0;i < n; i++)
{
//fout << included[i] << " ";
if(included[i] == 0)
{
//fout << word[i] <<"\n";
//words[newN] = word[i];
w[newN] = i;
newN++;
}
}
//fout << newN <<"\n";
n = newN;
//fout << newN<<"\n";
for(i = 0; i < n; i++)
{
//fout << word[w[i]] << "\n";
}
/*for(int i = 0; i < n; i++)
{
//fout << word[i] << "\n";
for(int j = 0; j < n; j++)
{
///cel mai lung sufix al lui i care este prefix al lui j
//aux[i][j] = getPrefix(word[i], word[j]);
//fout <<i <<" "<<j <"\n";
if(i != j)
{
getPrefix(words[i], words[j], i, j);
//fout << i <<" "<<j <<" " <<aux[i][j]<<"\n";
}
}
}*/
for(i = 0; i < n;i++)
{
//fout << word[i].size() - 1 <<"\n";
d[(1 << i)][i] = lung[w[i]];
last[(1 << i)][i] = -1;
}
for(int stare = 1; stare < 1 << n; stare++)
//for(int stare = 1; stare < 2; stare++)
{
for(i = 0; i < n; i++)
{
if(d[stare][i] != INF)
{
//fout << stare<<" "<<i<<"\n";
for(j = 0; j <n; j++)
{
if(i != j && ((stare & (1 << j) )== 0))
{
//fout <<
int lPrefix = aux[w[i]][w[j]];
int value = lung[w[j]] - aux[w[i]][w[j]];
if(d[(stare + (1 << j))][j] > d[stare][i] + value)
{
d[(stare + (1 << j))][j] = d[stare][i] + value;
// fout <<"noua dinamica " << (stare + (1 << j)) <<" " << d[stare][i] + value <<"\n";
last[(stare + (1 << j))][j] = i;
}
}
}
}
}
//fout << stare << "\n";
}
int minim = INF;
int pos = -1;
for(i = 0; i < n; i++)
{
//fout << d[(1 << n) - 1][i] <<"\n";
if(minim > d[(1 << n) - 1][i])
{
minim = d[(1 << n) - 1][i];
pos = i;
}
}
//fout << pos<<"\n";
int stare = (1 << n) - 1;
string sol = "";
while(last[stare][pos] != -1)
{
//fout << words[pos] <<"\n";
int newPos = last[stare][pos];
int nr = aux[w[newPos]][w[pos]];
string aux = "";
//for(i = nr+1; i <= lung[w[pos]]; i++)
for(i = lung[w[pos]]; i >= nr + 1; i--)
{
//aux = aux + word[w[pos]][i];
sol = word[w[pos]][i] + sol;
// fout << words[pos][i];
}
//fout <<"\n";
sol = aux + sol;
stare = stare - (1 << pos);
pos = newPos;
}
sol = word[w[pos]] + sol;
sol.erase(0, 1);
fout << sol << "\n";
//fout << words[pos];
//fout <<d[30][4]<<"\n";
}