[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.递归从实质上是一种数学的解决问题的思维,是一种分而治之的思 ...
随机推荐
- ubuntu 18.04用apt安装mysql-server
mysql5.7安装完成后普通用户不能进mysql 原因:root的plugin被修改成了auth_socket,用密码登陆的plugin应该是mysql_native_password,直接用roo ...
- runR
Linux下使用R 运行linux下的R脚本 编写R文件 新建后缀名为R的文件 写入R程序 在脚本首行加入 1 运行R文件 这里有两种方式 大专栏 runR进入R的环境">进入R的环 ...
- 初窥Android AudioFlinger
Android AudioFlinger 是Android音频系统的两大服务之一,另一个服务是AudioPolicyService,这两大服务都在系统启动时有MediaSever加载,加载的代码位于 ...
- 开发过程中关于JSON的那些事
在使用过程中,对JSON了解的还不够,特地整理一下,用于个人学习和知识参考. 1.IBM的json入门指南 json官网 2.javaweb中发送接收解析问题 3.Java解析json,以及js ...
- css进阶之二:flex弹性布局
布局模式是指一个盒子与其兄弟.祖先盒的关系决定其尺寸与位置的算法.css2.1中定义了四种布局模式,分别是块布局.行内布局.表格布局.以及定位布局.css3引入了新的布局模式Flexbox布局,灵活度 ...
- web系统是否要前后端分离?
开发一个web管理系统,是否要采用如今流行的前后端分离模式? 首先要从为什么会出现前后端分离说起,前后端分离的目的. 1.让前端工程师(前端)和后端工程师(后端)们能够更加专注于自己的领域 传统的开发 ...
- 压力测试(七)-html可视化压测报告细讲
1.阿里云Linux服务器 Jmeter压测实战之jtl文件生成和查看 简介: 利用软件从阿里云Centos服务器下载压测报告,讲解Jtl文件,并怎么查看文件 可以通过打开jmeter,新建线程组-& ...
- TensorFlow CPU环境 SSE/AVX/FMA 指令集编译
TensorFlow CPU环境 SSE/AVX/FMA 指令集编译 sess.run()出现如下Warning W tensorflow/core/platform/cpu_feature_guar ...
- python数据分析工具 | numpy
Python中没有提供数组功能,虽然列表可以完成基本的数组功能,但并不是真正的数组,而且在数据量较大时,使用列表的速度回非常慢.因此,Numpy提供了真正的数组功能,以及对数据进行快速处理的函数.Nu ...
- 【猫狗数据集】谷歌colab之使用pytorch读取自己数据集(猫狗数据集)
之前在:https://www.cnblogs.com/xiximayou/p/12398285.html创建好了数据集,将它上传到谷歌colab 在colab上的目录如下: 在utils中的rdat ...