zoukankan      html  css  js  c++  java
  • [DBSDFZOJ 多校联训] Password

    Password

    password.in/.out

    描述

    你来到了一个庙前,庙牌上有一个仅包含小写字母的字符串 s。

    传说打开庙门的密码是这个字符串的一个子串 t,并且 t 既是 s 的前缀又是 s 的后缀并且还在 s 的中间位置出现过一次。

    如果存在这样的串,请你输出这个串,如有多个满足条件的串,输出最长的那一个。

    如果不存在这样的串,输出"Just a legend"(去掉引号)。

    输入格式

    仅一行,字符串 s。

    输出格式

    如题所述

    样例输入

    fixprefixsuffix

    样例输出:

    fix

    数据范围

    对于 60%的数据, s 的长度<=100

    对于 100%的数据, s 的长度<=100000

    看到"同时是前缀与后缀的串的长度"可能大家都能想到 $KMP$ 算法w

    但是题目对于这个串有一定限制: 必须在中间出现过至少一次. 所以我们计算出这个串的长度之后还要拿着这个串进原串匹配一发, 如果匹配次数达到 $3$ 或以上就说明这个串除了在两端出现过之外还在中间出现了至少一次. 如果没有在中间出现则在刚刚验证失败的子串内接着找同时是这个串前缀与后缀的串的最大长度.

    也就是说先求 $KMP$ 中的失配边, 然后在不符合题意的时候一直跳失配边就好了.

    跳到最后还是没有匹配到说明无解.

    (考试的时候输入数据神特么文件尾没有空行(╯‵□′)╯︵┻━┻逐字符读入直接死循环然后本来能A的题...裱死出数据的家伙)

    参考代码:

    GitHub

     1 #include <cctype>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <iostream>
     6 #include <algorithm>
     7 
     8 const int MAXN=100010;
     9 
    10 int len;
    11 int fail[MAXN];
    12 char buffer[MAXN];
    13 
    14 int Read(char*);
    15 void Print(char*,int);
    16 void KMP(char*,int*,int);
    17 int Match(char*,int,char*,int,int*);
    18 
    19 int main(){
    20     scanf("%s",buffer);
    21     len=strlen(buffer);
    22     KMP(buffer,fail,len);
    23     for(int k=fail[len];k>0;k=fail[k]){
    24         if(Match(buffer,len,buffer,k,fail)>2){
    25             Print(buffer,k);
    26             return 0;
    27         }
    28     }
    29     puts("Just a legend");
    30     return 0;
    31 }
    32 
    33 void KMP(char* buf,int* f,int len){
    34     int j=0,k=-1;
    35     f[0]=-1;
    36     while(j<len){
    37         if(k==-1||buf[j]==buf[k]){
    38             f[++j]=++k;
    39         }
    40         else k=f[k];
    41     }
    42 }
    43 
    44 int Match(char* buf,int lb,char* ptn,int lp,int* f){
    45     int j=0,ans=0;
    46     for(int i=0;i<lb;i++){
    47         while(j>0&&buf[i]!=ptn[j]) 
    48             j=f[j];
    49         if(buf[i]==ptn[j])
    50             j++;
    51         if(j==lp){
    52             ans++;
    53             j=f[j];
    54         }
    55     }
    56     return ans;
    57 }
    58 
    59 inline void Print(char* buf,int len){
    60     for(int i=0;i<len;i++){
    61         putchar(buf[i]);
    62     }
    63     putchar('
    ');
    64 }
    65 
    66 inline int Read(char* buf){
    67     int pos=0;
    68     do{
    69         buf[pos]=getchar();
    70     }while(isspace(buf[pos]));
    71     while(!isspace(buf[pos])&&buf[pos]!=EOF){
    72         buf[++pos]=getchar();
    73     }
    74     buf[pos]='';
    75     return pos;
    76 }
    Backup

  • 相关阅读:
    Git安装配置
    Openstack 错误日志查看方法
    keystone v3.0与2.0的区别
    Python远程调试Openstack
    openstack遇到的错误
    特别翔实的adaboost分类算法讲解 转的
    h5 html5 模拟时钟 页面
    js 面向对象 jquery 全局变量 封装
    HTML5 h5 微信 浮层 提示 点击右上角,从浏览器打开 pop.png
    jquery中ajax使用error调试错误的方法,实例分析了Ajax的使用方法与error函数调试错误的技巧
  • 原文地址:https://www.cnblogs.com/rvalue/p/7300024.html
Copyright © 2011-2022 走看看