• HDU 5510 Bazinga (2015沈阳现场赛,子串判断)


    Bazinga

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 214    Accepted Submission(s): 89


    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
     
    Source
     
     
    【题意】:
    n个字符串,找出最大的i,使得存在j 满足j<i 且Sj不是Si的字串。
     
    【解题思路】:
    看着是个水题本想直接上,看到一片TLE吓得上了个KMP的板。。。
    交了一发还是TLE,已经不想做了。。
    在某blog的指点下,先判断相邻两个串是否存在字串关系,若Si是Sj的字串,则i和j只需要kmp()一次即可~
    减少kmp()次数后800ms过了,,感觉还是不够优美
    搜了一下发现有各种做法,Hash、dp......
    有空再改,挖坑待填~~
     
    (代码写得丑==)
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<string>
     6 #include<algorithm>
     7 #define eps 1e-8
     8 #define zero(x)(((x)>0?(x):-(x))<eps)
     9 #define PI acos(-1.0)
    10 #define LL long long
    11 #define maxn 2200
    12 #define IN freopen("in.txt","r",stdin);
    13 using namespace std;
    14 
    15 char Str[550][2200];
    16 /*KMP--字符串匹配--单一模版串*/
    17 //char str[maxn],p[maxn];/*p is template string*/
    18 int f[maxn],cnt;//when failed,get to f[i];
    19 void getf(char *p)
    20 {
    21     memset(f,0,sizeof(f));
    22     int len=strlen(p);  /* only cal once, or TLE */
    23     for(int i=1;i<len;i++)
    24     {
    25         int j=f[i];
    26         while(j&&p[i]!=p[j]) j=f[j];
    27         f[i+1]=(p[i]==p[j]? j+1:0);
    28     }
    29 }
    30 int kmp(char *str,char *p)    /*O(len1+len2)*/
    31 {
    32     getf(p);
    33     cnt=0;
    34     int len1=strlen(str),len2=strlen(p);    /* only cal once, or TLE*/
    35     for(int i=0,j=0;i<len1;i++)
    36     {
    37         while(j&&str[i]!=p[j]) j=f[j];
    38         if(str[i]==p[j]) j++;
    39         if(j==len2) cnt++;/*Match success*/
    40         if(cnt!=0) break;
    41     }
    42     return cnt;
    43 }
    44 
    45 int main(int argc, char const *argv[])
    46 {
    47     //IN;
    48 
    49     int t,ca=1;scanf("%d",&t);
    50     while(t--)
    51     {
    52         int n;scanf("%d",&n);
    53         for(int i=1;i<=n;i++) scanf("%s",Str[i]);
    54 
    55         int flag[maxn]={0};
    56         for(int i=1;i<n;i++)
    57             if(kmp(Str[i+1],Str[i])!=0) flag[i]=1;
    58 
    59         for(int i=n;i>=1;i--){
    60             for(int j=1;j<i;j++){
    61                 if(flag[j]) continue;
    62                 kmp(Str[i],Str[j]);
    63                 if(cnt==0){
    64                     printf("Case #%d: %d
    ",ca++,i);goto s;
    65                 }
    66             }
    67         }
    68 
    69         printf("Case #%d: -1
    ",ca++);
    70         s:continue;
    71     }
    72 
    73     return 0;
    74 }
     
  • 相关阅读:
    坚决不再犯的脑残错误
    2018.8.21提高A&省选组模拟考试
    2018.10.9模拟考试
    fread()快读
    2018.10.6模拟考试
    2018.10.4模拟考试
    2018.8.20提高AB组模拟考试
    2018.8.21提高AB组模拟考试
    2018.8.19提高B组模拟考试
    2018.8.18提高B组模拟试题
  • 原文地址:https://www.cnblogs.com/Sunshine-tcf/p/4926609.html
Copyright © 2020-2023  润新知