Manthan, Codefest 16 C. Spy Syndrome 2 ★

来源:互联网 发布:手指充电软件下载 编辑:程序博客网 时间:2024/06/01 23:39

题意:

Yash对自己的一段话加密:

1.将所有大写字母转成小写

2.将每个单词翻转

3.去除所有空格


现给出这段话中可能出现的一些单词,问这段话的原话是什么?

若有多种解输出任意一种


题解:

注意到单词数不超过1000000,考虑建立一棵trie

原话字符<=10000,那么从左到右for一遍尝试找解,又字符长度<=1000所以每个位置的查询向左1000位即可。tri可以以小写字符存储,找到存在的单词点输出对应位置原单词,降低编写难度

O(n*w)


是啊 直接倒着处理,对于节点i向前查找到某一个已经匹配的位置并且这段长度存在某个单词就记录就好了。我还在想,先把字符串倒序,然后当前位置往后能匹配哪些字符串,卡死在怎么处理这些东西,搜索?好像会超时。

换个思路 立马就出来了,唉 还是太年轻


#include<iostream>#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>#include<cmath>#include<vector>#include<queue>using namespace std;const int maxn = 1E4 + 10;struct T{int ch[26];int END;T () {memset(ch,0,sizeof(ch)); END = 0;}}t[1000010];int cnt,n,m,f[maxn],last[maxn];char x[maxn],y[1010];vector <char> v[maxn*10];void Insert(int o,int pos,int len,int num){for (; pos < len; pos++) {int to;if (y[pos] >= 'a') to = y[pos]-'a';else to = y[pos]-'A';if (!t[o].ch[to]) t[o].ch[to] = ++cnt;o = t[o].ch[to];}t[o].END = num;}void solve(int pos){int END = max(1,pos-999);int o = 0;for (int i = pos; i >= END; i--) {o = t[o].ch[x[i]-'a'];if (!o) break;if ((f[i-1] || i == 1) && t[o].END) {last[pos] = i;f[pos] = t[o].END; break;}}}void pri(int pos){if (last[pos] != 1) pri(last[pos]-1);int len = v[f[pos]].size();for (int i = 0; i < len; i++) printf("%c",v[f[pos]][i]);printf(" ");}int main(){#ifdef YZY   freopen("yzy.txt","r",stdin);#endifcin >> n;scanf("%s",1+x);cin >> m;for (int i = 1; i <= m; i++) {scanf("%s",&y);int len = strlen(y);Insert(0,0,len,i);for (int j = 0; j < len; j++) v[i].push_back(y[j]);}for (int i = 1; i <= n; i++) solve(i);pri(n);return 0;}


题意:

Yash对自己的一段话加密:

1.将所有大写字母转成小写

2.将每个单词翻转

3.去除所有空格


现给出这段话中可能出现的一些单词,问这段话的原话是什么?

若有多种解输出任意一种


题解:

注意到单词数不超过1000000,考虑建立一棵trie

原话字符<=10000,那么从左到右for一遍尝试找解,又字符长度<=1000所以每个位置的查询向左1000位即可。tri可以以小写字符存储,找到存在的单词点输出对应位置原单词,降低编写难度

O(n*w)

0 0
原创粉丝点击