ACM2015沈阳:B-Bazinga
2019.1.24
数据范围:\(n<=500,m<=2000\)
这个题最裸的暴力就是对于每个字符串,都去验证一次,时间复杂度\(O(n^2m)\)
我们发现,如果对于字符串\(i\),前\(i-1\)个字符串都是它的子串,假如存在一个字符串\(j\),使得\(i\)是\(j\)的子串,那么\(j\)就不需要去验证前\(i-1\)个字符串
这样就很好想到,我们对于字符串\(i\),只需要记下\(i-1\)中最后一个不是它子串的字符串,就能将时间复杂度优化到\(O(nm)\)
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
void read(int &x) {
char ch; bool ok;
for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
}
const int maxn=2e4+1;
#define rg register
char a[501][maxn];
int T,n,lst[501],nxt[501][maxn],ans,num;
void prepare(int x)
{
int n=strlen(a[x]+1);
for(rg int i=2,j=1;i<=n;i++)
{
while(j&&a[x][j]!=a[x][i])j=nxt[x][j];
if(a[x][j]==a[x][i])nxt[x][i]=j;
j++;
}
}
bool kmp(int x,int y)
{
int n=strlen(a[x]+1),m=strlen(a[y]+1);
for(rg int i=1,j=0;i<=n;i++)
{
while(j&&a[x][i]!=a[y][j+1])j=nxt[y][j];
if(a[x][i]==a[y][j+1])j++;
if(j==m)return 0;
}
return 1;
}
int main()
{
read(T);
while(T--)
{
read(n);ans=-1;
memset(lst,0,sizeof lst);
for(rg int i=1;i<=n;i++)scanf("%s",a[i]+1),prepare(i);
for(rg int i=1;i<=n;i++)
{
for(rg int j=i-1;j;j=lst[j])if(kmp(i,j)){lst[i]=j;break;}
if(lst[i])ans=i;
}
printf("Case #%d: %d\n",++num,ans);
}
}
ACM2015沈阳:B-Bazinga的更多相关文章
- HDU 5510 Bazinga (2015沈阳现场赛,子串判断)
Bazinga Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- hdu 5510 Bazinga (kmp+dfs剪枝) 2015ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)
废话: 这道题很是花了我一番功夫.首先,我不会kmp算法,还专门学了一下这个算法.其次,即使会用kmp,但是如果暴力枚举的话,还是毫无疑问会爆掉.因此在dfs的基础上加上两次剪枝解决了这道题. 题意: ...
- 2015ACM/ICPC亚洲区沈阳站-重现赛 B - Bazinga (KMP)
题意:给你\(n\)个字符串,\(s_1,s_2,...,s_n\),对于\(i(1\le i\le n)\),找到最大的\(i\),并且满足\(s_j(1\le j<i)\)不是\(s_i\) ...
- 2015ACM/ICPC亚洲区沈阳站 B-Bazinga
Bazinga Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- TTTTTTTTTTTTTTTT hdu 5510 Bazinga 字符串+哈希
Bazinga Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- Bazinga
Bazinga Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- 2016ACM/ICPC亚洲区沈阳站-重现赛赛题
今天做的沈阳站重现赛,自己还是太水,只做出两道签到题,另外两道看懂题意了,但是也没能做出来. 1. Thickest Burger Time Limit: 2000/1000 MS (Java/Oth ...
- 2015ACM/ICPC亚洲区沈阳站
5510 Bazinga 题意:给出n个字符串,求满足条件的最大下标值或层数 条件:该字符串之前存在不是 它的子串 的字符串 求解si是不是sj的子串,可以用kmp算法之类的. strstr是黑科技, ...
- HDU 5512 Pagodas (2015沈阳现场赛,找规律+gcd)
Pagodas Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
随机推荐
- Qt中的打印操作
Qt中对打印的支持是有一个独立的printsupport模块来完成的,所以,要想在程序中使用Qt的打印功能,必须先在pro文件中添加下面这句代码: QT += printsupport在这个模块中,提 ...
- TCP/IP,HTTP,Socket初识
在大学时候学过网络通信这一块,奈何已经还给老师,苍天饶过谁,该拾起来看看学学的还是要学,先简单了解了下这方面的知识,后续会继续通过看书来充实这方面的知识. 手机能够联网是手机底层实现了TCP/IP协议 ...
- webform中实现SQL Sever2008数据库数据分页查询
1 分页 1.1 数据库中存储过程 已知 当前页 pageIndex 页容量 pageSize 求 总页数 pageCou ...
- elasticsearch 中文分词(elasticsearch-analysis-ik)安装
elasticsearch 中文分词(elasticsearch-analysis-ik)安装 下载最新的发布版本 https://github.com/medcl/elasticsearch-ana ...
- LA-5059(组合游戏)
题意: 有n堆石子,分别有a1,a2,...,an个,两个游戏者轮流操作,每次可以选一堆m拿走至少一个且不超过一半的石子,谁不能拿石子就算输; 思路: a1太大打印sg表找规律,然后就是异或和了; A ...
- 【C/C++】任意大于1的整数分解成素数因子乘积的形式
// #include<stdio.h> #include<math.h> #include<malloc.h> int isprime(long n); void ...
- June 26,程序破解
1.android程序破解练习初级 方法一: 文件名:KeygenMe#1.apk工具:ApktoolGui v2.0 Final 先用ApktoolGui v2.0 Final反编译成java通过查 ...
- Android Developers - Training
Recently I've been contemplating to create a new App with the true "Android Design",new An ...
- Microsoft visual studio关闭安全检查
在用Microsoft visual studio进行代码编写时,使用到列如sprintlf这种比较旧的指令,需要关闭Microsoft visual studio的安全检查: 设置预处理选项:a. ...
- CF 622 F The Sum of the k-th Powers —— 拉格朗日插值
题目:http://codeforces.com/contest/622/problem/F 设 f(x) = 1^k + 2^k + ... + n^k 则 f(x) - f(x-1) = x^k ...