Pagini recente » Cod sursa (job #1286649) | Cod sursa (job #1396592) | Cod sursa (job #52808) | Cod sursa (job #1506573) | Cod sursa (job #686126)
Cod sursa(job #686126)
#include <fstream>
#include <vector>
#include <string>
#define INF 30001
#define FW(i,j) adn[i].size() <= adn[j].size() ? 0 : adn[i].size() - adn[j].size()
using namespace std;
bool out[18];
string adn[18];
vector<int> patterns[18];
void find_pat(int i)
{
patterns[i].push_back(-1);
patterns[i].push_back(0);
int pos = 2, back = 0;
while (pos < adn[i].size())
{
if(adn[i][pos-1] == adn[i][back])
{
++back;
patterns[i].push_back(back);
++pos;
}
else
if(back > 0)
back = patterns[i][back];
else
{
patterns[i].push_back(0);
++pos;
}
}
}
bool search(int i, int j)
{
int now = 0, x = 0;
while (now + x < adn[j].size())
{
if(adn[i][x] == adn[j][now+x])
{
if(x == adn[i].size() - 1)
return true;
else
++x;
}
else
{
now = now + x - patterns[i][x];
if(patterns[i][x] > -1)
x = patterns[i][x];
else
x = 0;
}
}
return false;
}
int supre(int i, int j)
{
for(int w = FW(i,j); w < adn[i].size(); ++w)
{
int now = 0, x = w;
while(adn[i][x] == adn[j][now])
{
if(x == adn[i].size() - 1)
return adn[i].size()-w;
++x; ++now;
}
}
return 0;
}
int main()
{
int n, graph[18][18];
ifstream in("adn.in");
in >> n;
for(int i = 0; i < n; ++i)
{
in >> adn[i];
find_pat(i);
}
for(int i = 0; i < n; ++i)
for(int j = 0; j < n; ++j)
{
if(adn[i].size()<adn[j].size())
if(search(i,j))
out[i] = true;
if(adn[i].size()==adn[j].size()&&adn[i]==adn[j]&&i!=j&&out[j]!=true)
out[i] = true;
}
int N=0, map[18];
for(int i = 0, j = 0; j < n; ++i, ++j)
{
j += out[j];
map[i] = j;
++N;
}
vector<int> a[18];
/*----Graph Contruction------------*/
for(int i = 0; i < N; ++i)
{
for(int j = 0; j < N; ++j)
{
if(i!=j)
graph[i][j] = supre(map[i],map[j]);
else
graph[i][j] = -1;
a[j].push_back(i);
}
}
int C[350][18];
for(int i = 0; i < (1<<N); ++i)
for(int j = 0; j < N; ++j)
C[i][j] = -1;
for(int i = 0; i < N; ++i)
{
C[1<<i][i] = 0;
}
int prev[18];
for(int i = 1; i < (1<<N); ++i)
{
for(int j = 0; j < N; ++j)
{
if(i & (1<<j))
for(int k = 0; k < a[j].size(); ++k)
if(i & (1<<a[j][k]))
{
if(C[i^(1<<j)][a[j][k]]!=-1&&C[i^(1<<j)][a[j][k]]+graph[a[j][k]][j]>C[i][j])
{
C[i][j] = C[i^(1<<j)][a[j][k]] + graph[a[j][k]][j];
prev[j] = a[j][k];
}
}
}
}
int res = -1, end;
for(int i = 0, w = 0; i < a[0].size(); ++i)
{
if(C[(1<<N)-1][a[0][i]]+graph[a[0][i]][0] > res)
{
res = C[(1<<N)-1][a[0][i]]+graph[a[0][i]][0];
end = i;
}
}
int min = graph[2][0], start = 0;
for(int i = 1; i < N; ++i)
{
if(graph[prev[i]][i]<min)
{
min = graph[prev[i]][i];
start = i;
}
}
vector<int> fin;
for(int i = prev[start], k = 1; i != prev[start] || k; i = prev[i], k = 0)
{
fin.push_back(i);
}
ofstream out("adn.out");
out << adn[map[fin[fin.size()-1]]];
for(int i = fin.size()-2; i>=0; --i)
{
for(int j = graph[fin[i+1]][fin[i]]; j < adn[map[fin[i]]].size(); ++j)
out << adn[map[fin[i]]][j];
}
out.close();
return 0;
}