zoukankan      html  css  js  c++  java
  • 2015ACM/ICPC亚洲区沈阳站-重现赛 1002 Bazinga

    http://acm.hdu.edu.cn/contests/contest_show.php?cid=645

    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:
    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

    题意:给出n个串s,下标i为1~n,找到最大的i,满足存在一个s[j](1 <= j < i)是s[i]的子串(实际上就是找每个串后面的不包含该串的串的最大下标)。

    利用KMP算法:可以求出每个串的Next数组,然后用KMP匹配每两个字符串,找到满足条件的最大下标。

    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #include<math.h>
    #include<stdlib.h>
    #include<algorithm>
    using namespace std;
    
    const int N=1e4+10;
    const int INF=0x3f3f3f3f;
    const int MOD=1e9+7;
    
    typedef long long LL;
    
    char s[510][2010];
    int Len[510], Next[510][2010]; ///Len数组保存每个字符串的长度
    
    void Getnext(int x) ///求出每个字符串的Next数组,保存在Next二维数组中
    {
        int i = 0, j = -1;
    
        Next[x][0] = -1;
    
        while (i <= Len[x])
        {
            if (j == -1 || s[x][j] == s[x][i])
            {
                i++;
                j++;
    
                Next[x][i] = j;
            }
            else j = Next[x][j];
        }
    }
    
    int main ()
    {
        int T, k = 0, i, j, x, y, ans, n;
    
        scanf("%d", &T);
    
        while (T--)
        {
            scanf("%d", &n);
    
            ans = -1;
            k++;
    
            for (i = 1; i <= n; i++)
            {
                scanf("%s", s[i]);
    
                Len[i] = strlen(s[i]);
                Getnext(i);
            }
    
            for (i = 1; i < n; i++) ///这个双重for循环就是要找到子串不是s[i]的字符串的最大下标
            {
                for (j = i+1; j <= n; j++)
                {
                    x = 0;
                    for (y = 0; y < Len[j]; y++)
                    {
                        while (s[i][x] != s[j][y] && x >= 0)
                            x = Next[i][x];
    
                        x++; ///如果两个字符串中的字符相等++
    
                        if (x == Len[i]) break; ///当等于长度时,说明s[i]在s[j]中匹配成功,那么s[j]这个字符串不满足条件
                    }
    
                    if (x == Len[i]) break;
                    else ans = max(ans, j); ///如果不等于长度,说明匹配不成功,那么s[i]不是s[j]的子串,更新满足条件的最大下标
                }
            }
    
            printf("Case #%d: %d
    ", k, ans);
        }
    
        return 0;
    }

     

  • 相关阅读:
    HDU_2191_多重背包
    HDU_1494_dp
    POJ_1088_dfs
    所有的畅通工程[HDU1232][HDU1874][HDU1875][HDU1879]
    畅通工程[HDU1863]
    还是畅通工程[HDU1233]
    最小生成树
    Who's in the Middle[HDU1157]
    Bungee Jumping[HDU1155]
    Is It A Tree?[HDU1325][PKU1308]
  • 原文地址:https://www.cnblogs.com/syhandll/p/4925754.html
Copyright © 2011-2022 走看看