hdu 5510 Bazinga (尺取法)

题目链接:点击此处

题目大意:

给出n个字符串,记为 S 1 , S 2 , S 3 . . . S n S_1,S_2,S_3...Sn S1,S2,S3...Sn 找到最大的 i i i ,使之满足:存在 j < i j<i j<i S j S_j Sj 不是 S i S_i Si 的子串

题目分析:
先讲一个名叫 s t r s t r ( s t r 1 , s t r 2 ) strstr(str1,str2) strstr(str1,str2) 的函数,其作用是判断字符串str2是否是str1的子串,如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL。一般认为这个函数的复杂度与kmp相同,但是极个别情况这个函数的复杂度会被卡到 O ( n 2 ) O(n^2) O(n2)
直接枚举 S i , S j S_i,S_j Si,Sj 复杂度为 O ( n 2 ) O(n^2) O(n2) 加上一点细节处理减小复杂度可以过
这里讲一种 O ( n ) O(n) O(n) 的尺取做法:
如果 S l S_l Sl S r S_r Sr 的字串显然可以让 l l l ++ 因为只需要存在一个 l < r l<r l<r S l S_l Sl 不是 S r S_r Sr 的子串即可而不是需要不存在 S r S_r Sr 的子串
如果 S l S_l Sl 不是 S r S_r Sr 的字串使,那么此时的 r r r 就是我们当前的局部最优解用 a n s ans ans 记录即可
其余细节见代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

#define ll long long
#define inf 0x3f3f3f3f
using namespace std;

int read()//习惯用快读
{
	int res = 0,flag = 1;
	char ch = getchar();
	while(ch<'0' || ch>'9')
	{
		if(ch == '-') flag = -1;
		ch = getchar();
	}
	while(ch>='0' && ch<='9')
	{
		res = (res<<3)+(res<<1)+(ch^48);//res*10+ch-'0';
		ch = getchar();
	}
	return res*flag;
}
const int maxn = 2e3+5;
char s[505][maxn];
int main()
{
	int t = read(),cas = 0;
	while(t--)
	{
		int n = read(),ans = -1;
		for(register int i = 1;i <= n;++i)
			scanf("%s",s[i]);
		int l = 1;
		for(int r = 2;r <= n;r++)
		{
			while(l < r)
			{
				if(strstr(s[r],s[l])) l++;
				else {
					ans = r;
					break;
				}
			}
		}
		printf("Case #%d: %d\n",++cas,ans);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值