杭电acm 5510Bazinga(字符串)

来源:互联网 发布:windows系统截屏快捷键 编辑:程序博客网 时间:2024/05/16 01:53

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 (1in) such that there exists an integer j (1j<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 (1t50) which is the number of test cases.
For each test case, the first line is the positive integer n (1n500) 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
45ababczabcabcdzabcd4youlovinyouaboutlovinyouallaboutlovinyou5dedefabcdabcdeabcdef3abaccc
 

Sample Output
Case #1: 4Case #2: -1Case #3: 4Case #4: 3
 

Source
2015ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)
题意:输入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<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;
}
原创粉丝点击