zoukankan      html  css  js  c++  java
  • CodeForces 126B Password

    题目链接:http://codeforces.com/problemset/problem/126/B

    题目大意:

    多组数据
    每组给定1个字符串S,问是否存在S的一个尽量长的子串,同时是S的前缀和后缀,并且在S的中间出现过(即非前缀也非后缀)。

    分析:

      利用KMP的next数组。
    首先next[i]表示该位(不包括)往前数next[i]位恰好构成字符串S的一个前缀,假设字符串长度为len,那next[len]就表示S长为next[len]的后缀正好是S的前缀,恰好就是题目说的公共前后缀,于是想知道S中间有没有这个公共前后缀只要搜一遍next数组,从1~len-1,看有没有等于next[len],如果有就输出S的前next[len]个字符,没有就输出"Just a legend"。
      不过上面的方法存在漏铜,对于有的情况,自然是没问题的;对于没有的情况,就有疏漏:
      对于字符串“abdabsab”,next数组为{-1,0,0,0,1,2,0,1,2},显然是可以的;
      而对于字符串“abfabdabeabfab”,next数组为{-1,0,0,0,1,2,0,1,2,0,1,2,3,4,5},在这个案例里找5当然是找不到的,但确实存在子串“ab”,在开头结尾中间都出现过。在这种情况下,答案如果存在,它必然同时是“abfab”的前缀和后缀,也就是再让“abfab”自己和自己玩一次找公共前后缀得到长度为2,然后在next数组里搜2才行。那也就是说要递归?其实不用,设p = len,令p = next[p],直接在next中查p即可,还查不到就在做一次p = next[p],继续查,直到找到或找不到(p < 0)。这是为什么呢?原因还是“abfab”自己和自己玩,只不过这个“abfab”是开头那个,而p此时正好就是“abfab”再后一位的next值,直接就变成了求子问题,不需要递归。

    代码如下:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3  
     4 #define rep(i,n) for (int i = 0; i < (n); ++i)
     5 #define For(i,s,t) for (int i = (s); i <= (t); ++i)
     6 #define rFor(i,t,s) for (int i = (t); i >= (s); --i)
     7 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
     8 #define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i)
     9  
    10 #define pr(x) cout << #x << " = " << x << "  "
    11 #define prln(x) cout << #x << " = " << x << endl
    12  
    13 #define ALL(x) x.begin(),x.end()
    14 #define INS(x) inserter(x,x.begin())
    15  
    16 #define ms0(a) memset(a,0,sizeof(a))
    17 #define msI(a) memset(a,inf,sizeof(a))
    18  
    19 #define pii pair<int,int> 
    20 #define piii pair<pair<int,int>,int> 
    21 #define mp make_pair
    22 #define pb push_back
    23 #define fi first
    24 #define se second
    25  
    26 inline int gc(){
    27     static const int BUF = 1e7;
    28     static char buf[BUF], *bg = buf + BUF, *ed = bg;
    29      
    30     if(bg == ed) fread(bg = buf, 1, BUF, stdin);
    31     return *bg++;
    32 } 
    33  
    34 inline int ri(){
    35     int x = 0, f = 1, c = gc();
    36     for(; c<48||c>57; f = c=='-'?-1:f, c=gc());
    37     for(; c>47&&c<58; x = x*10 + c - 48, c=gc());
    38     return x*f;
    39 }
    40  
    41 typedef long long LL;
    42 const int maxN = 1e5 + 7;
    43  
    44 string s;
    45  
    46 void KMP_next(string &T, vector< int > &nxt) {
    47     nxt.resize(T.size() + 1);
    48     nxt[0] = -1;
    49      
    50     int t = -1, i = 0;
    51     while(i < T.size()) {
    52         (0 > t || T[i] == T[t]) ? nxt[++i] = ++t : t = nxt[t];
    53     }
    54 }
    55  
    56 int main(){
    57     while(cin >> s) {
    58         string ans = "";
    59         vector< int > nxt;
    60         KMP_next(s, nxt);
    61         unordered_set< int > si;
    62         rep(i, nxt.size() - 1) si.insert(nxt[i]);
    63          
    64         int p = nxt[nxt.size() - 1];
    65         while(p > 0) {
    66             if(si.find(p) != si.end()) {
    67                 ans = s.substr(0, p);
    68                 break;
    69             }
    70             p = nxt[p];
    71         }
    72          
    73         if(ans == "") cout << "Just a legend
    ";
    74         else cout << ans << endl;
    75     }
    76      
    77     return 0;
    78 }
    View Code
  • 相关阅读:
    【Flume】数据采集引擎Flume
    【Spark】源码分析之SparkContext
    【Spark】源码分析之spark-submit
    【Hadoop故障处理】高可用(HA)环境DataNode问题
    【Hadoop故障处理】全分布下,DataNode进程正常启动,但是网页上不显示,并且DataNode节点为空
    【Hadoop故障处理】在高可用(HA)配置下,8088端口无法访问,resourcemanager进程无法启动问题
    【Spark】算子
    【Java】集合遍历--List和Map的多种遍历方式
    【Java】集合概述Collection、Map
    【Java】abstract,final,static,private,protected,public的区别
  • 原文地址:https://www.cnblogs.com/zaq19970105/p/10733023.html
Copyright © 2011-2022 走看看