http://acm.hdu.edu.cn/showproblem.php?pid=4763

Theme Section

Problem Description
 
It's time for music! A lot of popular musicians are invited to join us in the music festival. Each of them will play one of their representative songs. To make the programs more interesting and challenging, the hosts are going to add some constraints to the rhythm of the songs, i.e., each song is required to have a 'theme section'. The theme section shall be played at the beginning, the middle, and the end of each song. More specifically, given a theme section E, the song will be in the format of 'EAEBE', where section A and section B could have arbitrary number of notes. Note that there are 26 types of notes, denoted by lower case letters 'a' - 'z'.
To get well prepared for the festival, the hosts want to know the maximum possible length of the theme section of each song. Can you help us?
 
Input
 
The integer N in the first line denotes the total number of songs in the festival. Each of the following N lines consists of one string, indicating the notes of the i-th (1 <= i <= N) song. The length of the string will not exceed 10^6.
Output
 
There will be N lines in the output, where the i-th line denotes the maximum possible length of the theme section of the i-th song.
 
Sample Input
 
5
xy
abc
aaa
aaaaba
aaxoaaaaa
 
Sample Output
0
0
1
1
2
 
题意:一条串可以分成前中后三个部分,求三个部分最长的相同子串的长度。
思路:做了好久的KMP一直只会模板题,坚持不看题解,终于花了半天时间搞出这道偏水的题目,主要在于 中间的部分 的定义,该串不包含前面,也不包含后面的部分就是中间,理解错题意瞎搞了好久。我的做法是先劈成三部分,然后先对前后用kmp算最长的公共前后缀长度,然后再把前后缀部分保留,其他全部给中间部分,然后分别再对前面和中间,后面和中间用kmp算出最长的公共子串长度,然后取较小者即可。算是一个比较暴力无脑的做法吧= =。
 

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
#define N 1000005
string s;
string le, ri, mi, temp;
int nxt[N]; void make_next(string s)
{
memset(nxt, , sizeof(nxt));
int l = s.size();
int j = -, i = ;
nxt[] = -;
while(i < l) {
if(j == - || s[j] == s[i]) {
j++; i++;
nxt[i] = j;
} else {
j = nxt[j];
}
}
}
/*
前面的串和后面的串匹配的时候只能前后缀匹配传入0
前面的串和中间的串匹配或者后面的串和中间的串匹配传入1
*/
int kmp(string s, string str, int flag)
{
int l = s.size(), L = str.size();
make_next(s);
int i = , j = ;
while(i < L && j < l) {
if(j == - || s[j] == str[i]) {
i++; j++;
if(flag && j==l) return j;
} else {
j = nxt[j];
}
}
if(i == L) return j;
return ;
} int main()
{
int t;
cin >> t;
while(t--) {
s.clear();
temp.clear();
mi.clear();
le.clear();
ri.clear();
cin >> s;
int len = s.size();
if(len < ) {
puts(""); continue;
}
for(int i = ; i < len; i++) {
if(i <= len/ - ) {
le += s[i];
} else if(i >= len*/) {
ri += s[i];
} else {
mi += s[i];
}
}//将一条串拆成三部分 int lo = kmp(le, ri, );
if(lo == ) {
puts(""); continue;
}
//lo是公共前后缀长度
// }
for(int i = ; i < ri.size()-lo; i++)
mi += ri[i]; for(int i = lo; i < le.size(); i++) {
temp += le[i];
} int l = le.size(), r = ri.size(); ri.erase(, r - lo);
le.erase(lo, r);
temp += mi; int ans = ;
int k = kmp(le, temp, );
int g = kmp(ri, temp, );
ans = min(k, g); cout << ans << endl;
}
return ;
}

最新文章

  1. List和Dictionary泛型类查找效率浅析
  2. oracle删除表以及清理表空间
  3. 不允许修改SQLserver2008r2表中字段的属性问题
  4. PowerPivot安装完成后创建网站或网站集报错解决办法
  5. git svn rebase出现了checksum mismatch的错误
  6. PHP生成各种验证码和Ajax验证
  7. delphi 提取字符中的数字
  8. GUI编程笔记(java)01:GUI和CLI
  9. 关于angularjs的$state.go()与ui-sref传参问题
  10. Spring自学教程-注解的使用(三)
  11. 修改Linux内核参数提高Nginx服务器并发性能
  12. Hadoop源码学习之HDFS(一)
  13. Vibrator控制手机震动
  14. Sql基础(零基础学数据库_SqlServer版)
  15. 从url中获得域名
  16. LabVIEW(十):数组和簇
  17. Eureka多机高可用
  18. 宝塔Linux面板 概述
  19. MSF 内网渗透笔记
  20. P1314 聪明的质监员

热门文章

  1. 你好,Oh My Zsh - 社区力量全新方式定义命令行 | 咖啡时间
  2. [GEiv]第七章:着色器 高效GPU渲染方案
  3. WPF实现选项卡效果(2)——动态添加AvalonDock选项卡
  4. 赵伟国辞去TCL集团董事等职位,紫光参与TCL定增浮盈已超7亿
  5. ELINK编程器典型场景之多APP文件下载
  6. C++和QML混合的QT程序调试方法
  7. 如何替换Windows的Shell(即explorer.exe)
  8. 核心思想:许多公司都没有认识到云储存的革命性(类似QQ把它搞成了用户的家、再也离不开了)
  9. CopyMemory、FillMemory、MoveMemory、ZeroMemory
  10. 用python的curl和lxml来抓取和分析网页内容