forked from luliyucoordinate/Leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path0943.cpp
137 lines (125 loc) · 4.13 KB
/
0943.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
static int x = []() {std::ios::sync_with_stdio(false); cin.tie(0); return 0; }();
class Solution
{
const short validMask[12] = {0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80,0x100,0x200,0x400,0x800};
class MyNode;
vector<MyNode> nodes;
class MyNode {
public:
MyNode(short i, short N, string s):idx(i),min(0x3FFF),str(s){edges.resize(N,-1);}
short idx;
short min;
vector<short> edges;
string str;
};
class MyState {
public:
MyState(short c, short d, short v, MyState* p):cur(c),dis(d),valid(v),prevState(p){}
short cur;
short dis;
short valid;
MyState* prevState;
void print() {cout << cur << " " << dis << " " << valid << endl;}
};
struct MyStateCmp {
bool operator()(const MyState* a, const MyState* b) {
return a->dis > b->dis;
}
};
string shortestSuperstring(vector<string>& A)
{
int N = A.size();
short validFull = (1<<N)-1;
nodes.clear();
for (int i = 0; i < N; ++i) nodes.push_back(MyNode(i,N,A[i]));
for (int i = 0; i < N; ++i)
{
MyNode& curNode = nodes[i];
const string & lStr = A[i];
for (int j = 0; j < N; ++j)
{
if (i == j) continue;
MyNode& nextNode = nodes[j];
const string & rStr = A[j];
int maxOverlap = min(lStr.size(),rStr.size());
for (int k = maxOverlap; k >= 0; --k)
{
bool flag = true;
for (int l = 0; l < k; ++l)
{
if (lStr[lStr.size()-k+l] != rStr[l])
{
flag = false;
break;
}
}
if (flag)
{
curNode.edges[j] = rStr.size()-k;
if (curNode.edges[j] < nextNode.min)
{
nextNode.min = curNode.edges[j];
}
break;
}
}
}
}
for (int i = 0; i < N; ++i)
{
MyNode& curNode = nodes[i];
for (int j = 0; j < N; ++j)
{
if (i == j) continue;
MyNode& nextNode = nodes[j];
curNode.edges[j] -= nextNode.min;
}
}
priority_queue<MyState*,vector<MyState*>,MyStateCmp> pq;
for (int i = 0; i < N; ++i)
{
pq.push(new MyState(i,A[i].size()-nodes[i].min,validFull^validMask[i],NULL));
}
int count = 0;
while (!pq.empty())
{
MyState* curState = pq.top(); pq.pop(); ++count;
if (curState->valid == 0)
{
stack<short> btS;
while(curState!=NULL) { btS.push(curState->cur); curState=curState->prevState; }
string ret = A[btS.top()];
while (!btS.empty())
{
short curI = btS.top(); btS.pop();
if (btS.empty()) break;
short nextI = btS.top();
ret += A[nextI].substr(A[nextI].size()-nodes[curI].edges[nextI]-nodes[nextI].min);
}
return ret;
}
else
{
for (int i = 0; i < N; ++i)
{
if (curState->valid & validMask[i])
{
short nextDis = curState->dis + nodes[curState->cur].edges[i];
pq.push(new MyState(i,nextDis,curState->valid^validMask[i],curState));
}
}
}
}
return "";
}
};
int main()
{
string A = {"catg","ctaagt","gcta","ttca","atgcatc"};
cout << Solution().shortestSuperstring(A);
return 0;
}