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

本文共 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

你可能感兴趣的文章
ZenShot 流水账(一)
查看>>
怎样从Java转换到Kotlin代码:现在就开始使用Kotlin(KAD 29)
查看>>
Java 执行CMD/DOS
查看>>
oracle容器化docker解决方案
查看>>
基于SOA分布式架构的dubbo框架基础学习篇
查看>>
关于链表的一个小程序
查看>>
java多线程--线程池的使用
查看>>
EL简介
查看>>
Redis虚拟内存介绍
查看>>
1326. Bottle Taps
查看>>
关于DataTable的两篇基础文章
查看>>
广告系统
查看>>
批量去除Teleport Pro整站下载文件冗余代码
查看>>
VS代码生成工具ReSharper使用手册:配置快捷键(转)
查看>>
Vue - 自定义事件
查看>>
Hibernate 参数设置一览表
查看>>
在centos7下安装.net core
查看>>
Oracle基本操作
查看>>
PLSQL导出对象的表结构和表数据
查看>>
iOS - UIRefreshControl
查看>>