首页 > 其他 > 详细

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

时间:2016-07-15 17:12:21      阅读:215      评论: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
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!