杭电acm 5510Bazinga(字符串)
Bazinga
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 4353 Accepted Submission(s): 1388
Problem Description
Ladies and gentlemen, please sit up straight.
Don't tilt your head. I'm serious.

For n given strings S1,S2,⋯,Sn, labelled from 1 to n, you should find the largest i (1≤i≤n) such that there exists an integer j (1≤j<i) and Sj is not a substring of Si.
A substring of a string Si is another string that occurs in Si. For example, ``ruiz" is a substring of ``ruizhang", and ``rzhang" is not a substring of ``ruizhang".
Don't tilt your head. I'm serious.
For n given strings S1,S2,⋯,Sn, labelled from 1 to n, you should find the largest i (1≤i≤n) such that there exists an integer j (1≤j<i) and Sj is not a substring of Si.
A substring of a string Si is another string that occurs in Si. For example, ``ruiz" is a substring of ``ruizhang", and ``rzhang" is not a substring of ``ruizhang".
Input
The first line contains an integer t (1≤t≤50) which
is the number of test cases.
For each test case, the first line is the positive integer n (1≤n≤500) and in the following n lines list are the strings S1,S2,⋯,Sn.
All strings are given in lower-case letters and strings are no longer than 2000 letters.
For each test case, the first line is the positive integer n (1≤n≤500) and in the following n lines list are the strings S1,S2,⋯,Sn.
All strings are given in lower-case letters and strings are no longer than 2000 letters.
Output
For each test case, output the largest label you get. If it does not exist, output −1.
Sample Input
4
5
ab
abc
zabc
abcd
zabcd
4
you
lovinyou
aboutlovinyou
allaboutlovinyou
5
de
def
abcd
abcde
abcdef
3
a
ba
ccc
Sample Output
Case #1: 4
Case #2: -1
Case #3: 4
Case #4: 3
Source
题意:输入n 然后输入n个字符串,求最大的i 要求1~i-1中有一个串不是i的子串?
想法:
先从后向前遍历每个字符串,每个字符串判断一下是否包含它前面一个字符串,找到i最大的不包含串。如果找不到,则为-1;否则用两个指针,p=i+1,q=i-1,每次判断q是否是p的子串,是的话q–,不是的话p++,直到有一方走到头位置。这样的理论复杂度为o(nm),m为字符串的总长度。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 505;
const int maxm = 2005;
int N, F[maxn];
char str[maxn][maxm];
int main ()
{
int cas;
scanf("%d", &cas);
for (int kcas = 1; kcas <= cas; kcas++)
{
scanf("%d", &N);
for (int i = 0; i < N; i++)
scanf("%s", str[i]);
int p = N-1;
while (p && strstr(str[p], str[p-1]) != NULL)
p--;
p++;
for (int i = p-2; i >= 0 && p < N; i--)
{
while (p < N && strstr(str[p], str[i]) == NULL)
p++;
}
if (p == 1)
p = -1;
printf("Case #%d: %d\n", kcas, p);
}
return 0;
}
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 505;
const int maxm = 2005;
int N, F[maxn];
char str[maxn][maxm];
int main ()
{
int cas;
scanf("%d", &cas);
for (int kcas = 1; kcas <= cas; kcas++)
{
scanf("%d", &N);
for (int i = 0; i < N; i++)
scanf("%s", str[i]);
int p = N-1;
while (p && strstr(str[p], str[p-1]) != NULL)
p--;
p++;
for (int i = p-2; i >= 0 && p < N; i--)
{
while (p < N && strstr(str[p], str[i]) == NULL)
p++;
}
if (p == 1)
p = -1;
printf("Case #%d: %d\n", kcas, p);
}
return 0;
}
代码二:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
typedef unsigned long long ULL;
#define SEED 1000000007
const int maxn = 2010;
const int N = 505;
int p[maxn], pos;
char s[N][maxn];
ULL k[maxn], Hash[maxn], hash_[maxn];
void init()
{
k[0] = 1;
for(int i = 1; i < maxn; i++)
k[i] = k[i-1] * SEED;
}
bool Pa(int len)
{
int id = p[pos-1];
int L = strlen(s[id]);
hash_[L] = 0;
for(int i = L-1; i >= 0; i--)
hash_[i] = hash_[i+1] * SEED + s[id][i]-'a'+1;
for(int i = 0; i <=len-L; i++)
{
if(hash_[0] == Hash[i]-Hash[i+L]*k[L])
return true;
}
return false;
}
int main()
{
int T, n, len, ans;
scanf("%d", &T);
init();
for(int cas = 1; cas <= T; cas++)
{
scanf("%d", &n);
pos = 0;
ans = -1;
for(int i = 1; i <= n; i++)
{
scanf("%s", s[i]);
len = strlen(s[i]);
Hash[len] = 0;
for(int j = len-1; j >= 0; j--)
Hash[j] = Hash[j+1] * SEED + s[i][j]-'a'+1;
while(pos)
{
if(Pa(len))
pos--;
else
{
ans = i;
break;
}
}
p[pos++] = i;
}
printf("Case #%d: %d\n", cas, ans);
}
return 0;
}
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
typedef unsigned long long ULL;
#define SEED 1000000007
const int maxn = 2010;
const int N = 505;
int p[maxn], pos;
char s[N][maxn];
ULL k[maxn], Hash[maxn], hash_[maxn];
void init()
{
k[0] = 1;
for(int i = 1; i < maxn; i++)
k[i] = k[i-1] * SEED;
}
bool Pa(int len)
{
int id = p[pos-1];
int L = strlen(s[id]);
hash_[L] = 0;
for(int i = L-1; i >= 0; i--)
hash_[i] = hash_[i+1] * SEED + s[id][i]-'a'+1;
for(int i = 0; i <=len-L; i++)
{
if(hash_[0] == Hash[i]-Hash[i+L]*k[L])
return true;
}
return false;
}
int main()
{
int T, n, len, ans;
scanf("%d", &T);
init();
for(int cas = 1; cas <= T; cas++)
{
scanf("%d", &n);
pos = 0;
ans = -1;
for(int i = 1; i <= n; i++)
{
scanf("%s", s[i]);
len = strlen(s[i]);
Hash[len] = 0;
for(int j = len-1; j >= 0; j--)
Hash[j] = Hash[j+1] * SEED + s[i][j]-'a'+1;
while(pos)
{
if(Pa(len))
pos--;
else
{
ans = i;
break;
}
}
p[pos++] = i;
}
printf("Case #%d: %d\n", cas, ans);
}
return 0;
}