CF633C Spy Syndrome 2
题面:把一句话加密:1.所有字母变成小写。2.翻转所有单词。3.去掉空格。然后给你一句加密后的字符串以及一些出现在原句和没有出现在原句的单词,让你还原原句。注意,每一个单词可以使用多次,如果有多个答案,输出其中任意一个。
trie树好题……
首先都能想到的是把所有单词建成一棵trie树,然后我是这么想的,对于加密后字符串,每句每一个字符作为单词结尾,然后倒着再trie树上跑,知道遇到一个单词,记录是第几个,最后输出。
但是这样是不对的,因为无法保证遇到一个单词后,这个单词之前的部分已经匹配好了,举个例子:High,加密后是hgih,然后给定的单词有 hi 和 high,当扫到最后一个字符'h'的时候,在trie树上得到的第一个单词是 hi,而hi之前的gh无法构成一个单词,所以gg。
因此,我们还要有一个pre数组,记录每一个匹配点的上一个是由哪一个匹配点转移过来的,在trie树上跑的时候,只有当前点构成一个单词,且这个单词的前一个字符是匹配点,才return。
最后沿着pre数组找到头,倒叙输出。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<stack>
#include<queue>
#include<vector>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-;
const int maxn = 1e4 + ;
const int maxm = 1e5 + ;
inline ll read()
{
ll ans = ;
char ch = getchar(), las = ' ';
while(!isdigit(ch)) las = ch, ch = getchar();
while(isdigit(ch)) ans = ans * + ch - '', ch = getchar();
if(las == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar(x % + '');
} int n, m;
char s[maxn], ss[maxm][]; int cnt = ;
struct Trie
{
int ch[], val;
Trie()
{
Mem(ch, ); val = ;
}
}t[maxm * ];
int getnum(char c)
{
return c >= 'a' ? c - 'a' : c - 'A';
}
void insert(int id, char *s)
{
int len = strlen(s);
for(int i = , now = ; i < len; ++i)
{
int c = getnum(s[i]);
if(!t[now].ch[c]) t[now].ch[c] = ++cnt;
now = t[now].ch[c];
if(i == len - ) t[now].val = id;
}
} int ans[maxn], pre[maxn];
void query(int x)
{
for(int i = x, now = ; i >= ; --i)
{
int c = getnum(s[i]);
if(!t[now].ch[c]) return;
now = t[now].ch[c];
if(t[now].val && (ans[i - ] || i == )) {pre[x] = i - , ans[x] = t[now].val; return;}
}
return;
} void print(int x)
{
if(pre[x] != -) print(pre[x]);
printf("%s ", ss[ans[x]]);
} int main()
{
n = read(); scanf("%s", s);
m = read();
for(int i = ; i <= m; ++i)
{
scanf("%s", ss[i]);
insert(i, ss[i]);
}
for(int i = ; i < n; ++i) query(i);
print(n - ); enter;
return ;
}
CF633C Spy Syndrome 2的更多相关文章
- CF633C Spy Syndrome 2 trie树
这个模型以前绝对见过,模拟赛的时候开始敲了一个AC自动机,纯属脑抽~ code: #include <bits/stdc++.h> #define N 5000006 #define NN ...
- Manthan, Codefest 16 -C. Spy Syndrome 2
time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...
- codeforces 633C. Spy Syndrome 2 hash
题目链接 C. Spy Syndrome 2 time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- Codeforces 633C Spy Syndrome 2 | Trie树裸题
Codeforces 633C Spy Syndrome 2 | Trie树裸题 一个由许多空格隔开的单词组成的字符串,进行了以下操作:把所有字符变成小写,把每个单词颠倒过来,然后去掉单词间的空格.已 ...
- Codeforce 633.C Spy Syndrome 2
C. Spy Syndrome 2 time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- Manthan, Codefest 16 C. Spy Syndrome 2 字典树 + dp
C. Spy Syndrome 2 题目连接: http://www.codeforces.com/contest/633/problem/C Description After observing ...
- CF#633C Spy Syndrome 2 DP+二分+hash
Spy Syndrome 2 题意 现在对某个英文句子,进行加密: 把所有的字母变成小写字母 把所有的单词反过来 去掉单词之间的空格 比如:Kira is childish and he hates ...
- Codeforce 633C. Spy Syndrome 2
C. Spy Syndrome 2 time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- CF633C:Spy Syndrome 2——题解
https://vjudge.net/problem/CodeForces-633C http://codeforces.com/problemset/problem/633/C 点击这里看巨佬题解 ...
随机推荐
- js正则表达式基本语法
正则表达式基本语法 两个特殊的符号'^'和'$'.他们的作用是分别指出一个字符串的开始和结束. 例子如下: "^The":表示所有以"The"开始的字符串(&q ...
- jenkins 部署应用
一,安装rpm包 安装jdk 安装jenkins 查看jdk是否安装成功 启动jenkins systemctl start jenkins 开机自启 systemctl enable jenkins ...
- GreenPlum 大数据平台--非并行备份(六)
一,非并行备份(pg_dump) 1) GP依然支持常规的PostgreSQL备份命令pg_dump和pg_dumpall 2) 备份将在Master主机上创建一个包含所有Segment数据的大的备份 ...
- shell特殊字符汇总【转】
Linux下无论如何都是要用到shell命令的,在Shell的实际使用中,有编程经验的很容易上手,但稍微有难度的是shell里面的那些个符号,各种特殊的符号在我们编写Shell脚本的时候如果能够用的好 ...
- Python 中的反射和自省
本文主要介绍Python中的反射和自省,以及该机制的简单应用 熟悉Java的程序员,一定经常和Class.forName打交道.即使不是经常亲自调用这个方法,但是在很多框架中(spring,eclip ...
- C++ Memory System Part2: 自定义new和delete
在第一部分中,我们介绍了new / delete的具体用法和背后的实现细节,这次我们将构建我们自己的小型工具集,可以使用我们自定义的allocator类来创建任意类型的实例(或者实例数组),我们需要做 ...
- js中的break,continue,return
js中的break,continue, return (转) 面向对象编程语法中我们会碰到break ,continue, return这三个常用的关键字,那么关于这三个关键字的使用具体的操作是什么呢 ...
- javascript移动端滑屏事件
来看看在pc上面的几个事件:onmousedown,onmousemove,onmouseup 我相信大家对这几个事件一定不陌生,第一个onmousedown表示鼠标按下,第二个onmousemove ...
- Windows未能启动 由于关键系统驱动程序丢失或损坏 电脑无法开机
该错误导致系统无法开机,其实也好解决 错误描述: Windows未能启动.原因可能是最近更改了硬盘或软件.解决此问题的步骤…… 1.…… 2.…… 3.…… …… 文件:\windows\system ...
- css之margin,padding的百分比
注意:上下内边距与左右内边距一致:即上下内边距的百分数会相对于父元素宽度设置,而不是相对于高度. PS:而且是基于父元素内容的宽度(width属性的大小),不是基于父元素整个框架的宽度