manthan

链接:https://codeforces.com/contest/633/problem/C
思路:好像有dp的方法,我直接建一个trie树然后上面跑dfs,对于非单词结点直接往下跑,如果是单词结点可以考虑回到0点(开始一个新单词),或者继续向下跑(另一个单词),最后用一个栈保存结果输出即可。

代码:

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

using namespace std;

const int maxnode = 1e6 + 100;
const int sigma_size = 26;
int ch[maxnode][sigma_size];
int val[maxnode];
int sz;
int n, m;
char s1[10010], s2[1010];
vector<char> r[100010];
stack<int> s;

void (){
sz = 1;
memset(ch[0], 0, sizeof(ch[0]));
}

int idx(char c){
return c - 'a';
}

void insert(char *s, int v){
int u = 0;
int n = strlen(s);
for(int i = 0; i < n; i++){
int c = idx(s[i]);
if(!ch[u][c]){
memset(ch[sz], 0, sizeof(ch[sz]));
val[sz] = 0;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = v;
}

void print(int x){
for(int i = 0; i < r[x].size(); i++){
putchar(r[x][i]);
}
putchar(' ');
}

bool dfs(int x, int d){
if(d == n && val[x]){
s.push(val[x]);
return true;
}
else if(d == n) return false;
int c = idx(s1[d]);
if(val[x]){
if(dfs(0, d)){
s.push(val[x]);
return true;
}
}

if(ch[x][c] && dfs(ch[x][c], d + 1)){
return true;
}
return false;
}

int main(){
init();
scanf("%d %s", &n, s1);
scanf("%d", &m);
for(int i = 1; i <= m; i++){
scanf("%s", s2);
int x = strlen(s2);
for(int j = 0; j < x; j++)r[i].push_back(s2[j]);
for(int j = 0; j < x / 2; j++)swap(s2[j], s2[x - j - 1]);
for(int j = 0; j < x; j++)s2[j] = tolower(s2[j]);
insert(s2, i);
}
dfs(0, 0);
while(!s.empty()){
int x = s.top();
s.pop();
print(x);
}
puts("");
return 0;
}