[kmp,不要过多调用strlen!!!] Codeforces 1200E Compress Words
题目:http://codeforces.com/contest/1200/problem/E
1 second
256 megabytes
standard input
standard output
Amugae has a sentence consisting of nn words. He want to compress this sentence into one word. Amugae doesn't like repetitions, so when he merges two words into one word, he removes the longest prefix of the second word that coincides with a suffix of the first word. For example, he merges "sample" and "please" into "samplease".
Amugae will merge his sentence left to right (i.e. first merge the first two words, then merge the result with the third word and so on). Write a program that prints the compressed word after the merging process ends.
The first line contains an integer nn (1≤n≤1051≤n≤105), the number of the words in Amugae's sentence.
The second line contains nn words separated by single space. Each words is non-empty and consists of uppercase and lowercase English letters and digits ('A', 'B', ..., 'Z', 'a', 'b', ..., 'z', '0', '1', ..., '9'). The total length of the words does not exceed 106106.
In the only line output the compressed word after the merging process ends as described in the problem.
5
I want to order pizza
Iwantorderpizza
5
sample please ease in out
sampleaseinout
题意:
给你n个字符串,你需要按顺序连接这些字符串,如果当前的字符串的前缀和上一个字符串的后缀相同,则连接时要去掉当前字符串的前缀
思路:
一开始暴力,果断TLE,然后用kmp,还是TLE,改了几十次后发现是每次调用kmp和getnex时都调用用了strlen,增加了复杂度,去掉之后就AC了
为什么用kmp呢?因为kmp可以在文本串中找到模板串匹配的部分,现在要当前字符串的前缀匹配上一个字符串的后缀,我们就从上一个字符串的长度-当前字符串的长度的位置开始找,
因为一个字符串的前缀最长是他本身,所以当前字符串的前缀最多能匹配到这个位置(再往前当前字符串的长度就不够了),然后用kmp匹配,然后返回一个当前字符串的前缀与上一个字符串的后缀不匹配的位置(就是return j,j是当前字符串匹配的位置,如果t[i]==p[j]则j++,所以返回时j会指向不匹配的位置)
注意:
如果调用太多次strlen会TLE!!!
#include<bits/stdc++.h>
using namespace std;
const int amn=1e6+;
char ans[amn],in[amn];
int n,nex[amn],len,tp;
void getnex(char in[]){ ///不要在这调用strlen!!!,用已有的就好了,不然会T到自闭!!!
nex[]=nex[]=;
for(int i=;i<len;i++){
int j=nex[i];
while(j&&in[i]!=in[j])j=nex[j];
nex[i+]=in[i]==in[j]?j+:;
}
}
int kmp(char t[],char p[],int pos){ ///不要在这调用strlen!!!,用已有的就好了,不然会T到自闭!!!
getnex(in);
int j=;
for(int i=pos;i<tp;i++){
while(j&&p[j]!=t[i])j=nex[j];
if(p[j]==t[i])j++;
}
return j;
}
int main(){
ios::sync_with_stdio();
cin>>n;
cin>>ans;
int pos;
tp=strlen(ans); ///注意,如果调用太多次strlen会TLE!!!
for(int i=;i<=n;i++){
cin>>in;
len=strlen(in);
pos=tp-len; ///上一个字符串的长度-当前字符串的长度,因为一个字符串的前缀最长是他本身,他最多只能匹配到这个位置
for(int j=kmp(ans,in,pos);j<len;j++)
ans[tp++]=in[j];
}
for(int i=;i<tp;i++)
printf("%c",ans[i]);
printf("\n");
}
/**
给你n个字符串,你需要按顺序连接这些字符串,如果当前的字符串的前缀和上一个字符串的后缀相同,则连接时要去掉当前字符串的前缀
一开始暴力,果断TLE,然后用kmp,还是TLE,改了几十次后发现是每次调用kmp和getnex时都调用用了strlen,增加了复杂度,去掉之后就AC了
为什么用kmp呢?因为kmp可以在文本串中找到模板串匹配的部分,现在要当前字符串的前缀匹配上一个字符串的后缀,我们就从上一个字符串的长度-当前字符串的长度的位置开始找,
因为一个字符串的前缀最长是他本身,所以当前字符串的前缀最多能匹配到这个位置(再往前当前字符串的长度就不够了),然后用kmp匹配,然后返回一个当前字符串的前缀与上一个字符串的后缀不匹配的位置(就是return j,j是当前字符串匹配的位置,如果t[i]==p[j]则j++,所以返回时j会指向不匹配的位置)
然后从这个位置开始把当前字符串后面的字符都加到上一个字符串后面,知道输入完毕,最后输出ans就行了
注意:如果调用太多次strlen会TLE!!!
**/
[kmp,不要过多调用strlen!!!] Codeforces 1200E Compress Words的更多相关文章
- CodeForces 1200E Compress Words
\(C_n^m\)的typora,点了一下启用源代码模式就把我已经写好的博客弄没了,就给我留个标题,自动保存也只给我保存了个标题--\(C_n^m\),wdnmd Time limit 1000 ms ...
- codeforces#1120C. Compress String(dp+后缀自动机)
题目链接: https://codeforces.com/contest/1120/problem/C 题意: 从前往后压缩一段字符串 有两种操作: 1.对于单个字符,压缩它花费$a$ 2.对于末尾一 ...
- Codeforces 1120C Compress String(DP)
题意:给你一个字符串,有2种消除方式:1:消除一个单独的字母,代价为a.2:s[j]到s[k]是s[1]到s[j - 1]的子串,那么s[j]到s[k]可以消除,代价为b,问最小的代价. 思路:官方题 ...
- CodeForces 25E Test KMP
Description Sometimes it is hard to prepare tests for programming problems. Now Bob is preparing tes ...
- KMP算法_读书笔记
下面是KMP算法的实现伪代码: KMP_MATCHER ( T, P ) . n = T.length . m = P.length . next = COMPUTE_PREFIX_FUNCTION ...
- 从暴力匹配到KMP算法
前言 现在有两个字符串:\(s1\)和\(s2\),现在要你输出\(s2\)在\(s1\)当中每一次出现的位置,你会怎么做? 暴力匹配算法 基本思路 用两个指针分别指向当前匹配到的位置,并对当前状态进 ...
- hdu4763 KMP
稀里糊涂1A开心.我做了2次kmp,先第一次利用next[],由于next[]前面一小段一直是一样的,所以可以根据这个来找.然后就找到了开头和结尾,还缺中间的部分. 中间的部分就是通过开头部分去模式匹 ...
- HDU 5763 Another Meaning (kmp + dp)
Another Meaning 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5763 Description As is known to all, ...
- C语言数据结构----递归的应用(斐波拉契数列、汉诺塔、strlen的递归算法)
本节主要说了递归的设计和算法实现,以及递归的基本例程斐波拉契数列.strlen的递归解法.汉诺塔和全排列递归算法. 一.递归的设计和实现 1.递归从实质上是一种数学的解决问题的思维,是一种分而治之的思 ...
随机推荐
- AndroidManifest.xml文件详解
本文为安全专家李洋的最新一篇专栏文章<AndroidManifest.xml文件详解>.AndroidManifest.xml是一个跟安全相关的配置文件,该配置文件是Android安全保障 ...
- 让百度和google收录我们的网站
花了几天时间终于把这个看似高大上的博客搞好了,但是发现只能通过在地址栏输入地址进行访问,这很明显和我装X装到底的性格,于是乎在查阅了嘟爷的博客,和我各种百度终于搞出来了. 让谷歌收录 让谷歌收录还是比 ...
- 2、【Spark】Spark环境搭建(集群方式)
Spark集群方式搭建结构如图所示,按照主从方式.
- 二进制原码、反码、补码以及Java中的<< 和 >> 和 >>> 详细分析
1.计算机二进制系统中最小单位bit 在计算机二进制系统中: bit (位) :数据存储的最小单元. 简记为b,也称为比特(bit),每个二进制数字0或1就是一个位(bit),其中,每 8bit = ...
- 【Amaple教程】5. 插件
Amaple 拥有非常强大插件功能,这也是它的突出功能之一,Amaple插件一般表现为功能块(函数)或功能块(包含一系列函数和属性的Object对象),它除了支持Amaple规范定义的插件外,还支持所 ...
- C++常数优化
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC target("avx") #pragma GCC opti ...
- 第八次——非确定的自动机NFA确定化为DFA
NFA 确定化为 DFA 子集法: f(q,a)={q1,q2,…,qn},状态集的子集 将{q1,q2,…,qn}看做一个状态A,去记录NFA读入输入符号之后可能达到的所有状态的集合. 步骤: 1. ...
- python自动化第一课 - python安装以及pycharm配置
1.安装python 1.1打开python官网https://www.python.org/downloads/windows/进行下载Python 3.8.0 1.2下载完毕后进行安装,1勾选 A ...
- 单链表反转的原理和python代码实现
链表是一种基础的数据结构,也是算法学习的重中之重.其中单链表反转是一个经常会被考察到的知识点. 单链表反转是将一个给定顺序的单链表通过算法转为逆序排列,尽管听起来很简单,但要通过算法实现也并不是非常容 ...
- 网络编程---socket模块
内容中代码都是先写 server端, 再写 client端 1 TCP和UDP对比 TCP(Transmission Control Protocol)可靠的.面向连接的协议(eg:打电话).传输效 ...