博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 5510 Bazinga KMP
阅读量:4312 次
发布时间:2019-06-06

本文共 1482 字,大约阅读时间需要 4 分钟。

题意:

\(n(1 \leq n \leq 500)\)个字符串,求一个最大的\(i\),使得存在一个\(S_{j}\)不是\(S_i\)的子串。

分析:

维护两个指针\(l,r\)

那么有两种情况:

  • 如果\(S_l\)\(S_r\)的子串,那么\(l\)++。
  • 如果\(S_l\)不是是\(S_r\)的子串,那么将答案更新为\(r\),然后\(r\)++。

考虑\(S_{r+1}\)的时候为什么同样不考虑\(S_l\)之前的串了呢?

因为\(S_l\)之前的串都是后面某个串的子串,所以如果他们中有不是\(S_{r+1}\)子串的串的话,那么一定有对应的那个串也不是\(S_{r+1}\)的子串。这样保证\(r\)一定能更新到\(ans\)
因此降了一维的复杂度。

#include 
#include
#include
using namespace std;const int maxn = 500 + 5;const int maxl = 2000 + 5;int f[maxl];char s[maxn][maxl];void getFail(char* s) { f[0] = f[1] = 0; for(int i = 1; s[i]; i++) { int j = f[i]; while(j && s[i] != s[j]) j = f[j]; f[i+1] = s[i] == s[j] ? j+1 : 0; }}bool match(char* T, char* P) { int n = strlen(T), m = strlen(P); getFail(P); int j = 0; for(int i = 0; i < n; i++) { while(j && P[j] != T[i]) j = f[j]; if(P[j] == T[i]) j++; if(j == m) return true; } return false;}int main(){ int T; scanf("%d", &T); for(int kase = 1; kase <= T; kase++) { int n; scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%s", s[i]); int L = 1, R, ans = -1; for(R = 2; R <= n; R++) { while(L < R) { if(match(s[R], s[L])) L++; else { ans = R; break; } } } printf("Case #%d: %d\n", kase, ans); } return 0;}

转载于:https://www.cnblogs.com/AOQNRMGYXLMV/p/4928452.html

你可能感兴趣的文章
如何退出 vim
查看>>
Robberies
查看>>
get post 提交
查看>>
R安装
查看>>
JavaScript高级特性-实现继承的七种方式
查看>>
20121016学习笔记四
查看>>
EntityFramework 学习 一 Stored Procedure
查看>>
Sliverlight之 故事板
查看>>
Java 必知必会的 20 种常用类库和 API
查看>>
HDU 1087 Super Jumping! Jumping! Jumping!
查看>>
0007_初始模块和字节码
查看>>
[效率提升]如何管理好你的电脑文件
查看>>
C++实验二
查看>>
SharePoint2010 富文本框添加图片功能的扩展
查看>>
零零碎碎的知识
查看>>
UNIX基础--用户和基本账户管理
查看>>
设计模式
查看>>
5.0以上机器XPOSED框架安装流程
查看>>
静态方法与非静态方法
查看>>
注释,字符串
查看>>