码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 633C Spy Syndrome 2(DP+Trie树)

时间:2016-07-15 17:14:15      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:

题目大概说给一个加密的字符串,加密规则是把原文转化成小写字母,然后各个单词反转,最后去掉空格。现在给几个已知的单词,还原加密的字符串。

UVa1401一个道理。。

  • 用dp[i]表示加密字符前i个字符都被解密时,最后所用单词编号,为0表示不能被解密
  • 然后转移一个样,从i出发往前在Trie树上跑,看看能否找到不为0的dp[j],而str[j+1]str[j+2]...str[i-1]str[i]是单词
  • 最后输出方案就根据dp里面的值从最后面回溯找到并输出即可

时间复杂度O(加密字符串长*单词最大长度)。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<string>
 5 #include<algorithm>
 6 using namespace std;
 7 #define MAXN 1111111
 8 int tn,ch[MAXN][26],flag[MAXN];
 9 void insert(const char *s,int k){
10     int x=0,y;
11     for(int i=0; s[i]; ++i){
12         if(s[i]>=A && s[i]<=Z) y=s[i]-A;
13         else y=s[i]-a;
14         if(ch[x][y]==0) ch[x][y]=++tn;
15         x=ch[x][y];
16     }
17     flag[x]=k;
18 }
19 
20 int d[11111];
21 char str[11111];
22 string word[110000];
23 void output(int n){
24     if(n<0) return;
25     output(n-word[d[n]].length());
26     cout<<word[d[n]]<< ;
27 }
28 int main(){
29     int n,m;
30     scanf("%d%s%d",&n,str,&m);
31     for(int i=1; i<=m; ++i){
32         cin>>word[i];
33         insert(word[i].c_str(),i);
34     }
35     for(int i=0; i<n; ++i){
36         int x=0;
37         for(int j=i; j>=0; --j){
38             int y=str[j]-a;
39             if(ch[x][y]==0) break;
40             x=ch[x][y];
41             if(flag[x] && (i-(i-j+1)<0 || d[i-(i-j+1)])){
42                 d[i]=flag[x];
43                 break;
44             }
45         }
46     }
47     output(n-1);
48     return 0;
49 }

 

Codeforces 633C Spy Syndrome 2(DP+Trie树)

标签:

原文地址:http://www.cnblogs.com/WABoss/p/5674098.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!