zoukankan      html  css  js  c++  java
  • POJ-2774

    Description

    Little cat在Byterland的首都读物理专业。这些天他收到了一条悲伤地信息:他的母亲生病了。担心买火车票花钱太多(Byterland是一个巨大的国家,因此他坐火车回家需要16小时),他决定只给母亲发短信。 
    Little cat的家境并不富裕,因此他经常去营业厅查看自己发短信花了多少钱。昨天营业厅的电脑坏掉了,打印出两条很长的信息。机智的little cat很快发现: 
    1.信息中所有的字符都是小写英文字母,没有标点和空格。 
    2.所有的短信都被连在了一起——第i+1条短信直接接在第i条短信后面——这就是这两条信息如此长的原因。 
    3.虽然他发的短信都被连在了一起,但由于电脑坏掉了,它们的左边或右边都可能会有许多冗余字符。 
    例如:如果短信是"motheriloveyou",电脑打印出的每条信息都可能是 "hahamotheriloveyou", "motheriloveyoureally", "motheriloveyouornot", "bbbmotheriloveyouaaa",等等。 
    4.因为这些乱七八糟的问题,little cat打印了两遍(所以有两条非常长的信息)。尽管原始的短信文本在两条信息中都一样,但两条信息在文本两侧的冗余字符都可能不一样。 
    给出这两条很长的信息,输出little cat写下的原始短信文本的最长可能长度。 
    背景: 
    在Byterland,短信按照美元/字节的单位计价。这就是little cat想要知道原始文本最长可能长度的原因。 
    为什么让你写一个程序?有四个原因: 
    1.little cat这些天忙于他的物理课程。 
    2.little cat不想透露他对母亲说了什么。 
    3.POJ是个好网站。 
    4.little cat想要从POJ那里挣点钱,并尝试说服他的母亲去医院

    Input

    两行两个由小写英文字母组成的字符串。字符串长度都不会超过100000

    Output

    一行一个整数,即little cat写下的原始文本的最长可能长度。

    Sample Input

    yeshowmuchiloveyoumydearmotherreallyicannotbelieveit 
    yeaphowmuchiloveyoumydearmother

    Sample Output

    27

    Hint

     

    Source

    POJ 2774 Long Long Message

    后缀数组, 字符串, 模式匹配

    这道题大意就是求两个字符串的最长公共子串。显然可以用后缀数组来做,但我太弱并不会。于是用字符串哈希来做。

     1 #include <map>
     2 #include <set>
     3 #include <cmath>
     4 #include <queue>
     5 #include <stack>
     6 #include <cstdio>
     7 #include <string>
     8 #include <vector>
     9 #include <cstring>
    10 #include <complex>
    11 #include <cstdlib>
    12 #include <iostream>
    13 #include <algorithm>
    14 #define ull unsigned long long
    15 
    16 using namespace std;
    17 
    18 inline int gi()
    19 {
    20     register int r = 0; register bool b = 1; register char c = getchar();
    21     while (c < '0' || c > '9') { if (c == '-') b = 0; c = getchar(); }
    22     while (c >= '0' && c <= '9') { r = r * 10 + c - '0', c = getchar(); }
    23     if (b) return r; return -r;
    24 }
    25 
    26 const int inf = 2147483647, N = 100005, base = 131;
    27 int n,m;
    28 ull p[N],a[N],h1[N],h2[N];
    29 char s[N],t[N];
    30 
    31 inline void gethash ()
    32 {
    33     register int i,len; len = max(n,m);
    34     p[0] = 1; for (i=1; i<=len; i++) p[i] = p[i-1] * base;  // 预处理 base 的 i 次方
    35     h1[0] = 0; for (i=1; i<=n; i++) h1[i] = h1[i-1] * base + s[i-1];  // hash 第一个字符串 注意 h1[i] 存的是前缀 i-1 的哈希值
    36     h2[0] = 0; for (i=1; i<=m; i++) h2[i] = h2[i-1] * base + t[i-1];  // hash 第二个字符串 同上
    37 }
    38 
    39 inline bool check (register int t)
    40 {
    41     register int i,tot; tot = 0;
    42     register ull h;
    43     for (i=t; i<=n; i++) a[tot++] = h1[i] - h1[i-t] * p[t];  //取出第一个字符串所有长度为 t 的子串的哈希值 所有长度为 t 的子串由前缀 i 去掉前缀 i-t 得到
    44     sort (a,a+tot);  //为 binary_search 做准备 binary_search 为二分查找一个数是否在一个数组中出现过
    45     for (i=t; i<=m; i++)
    46         {
    47             h = h2[i] - h2[i-t] * p[t];
    48             if (binary_search (a,a+tot,h)) return 1;  //枚举第二个串的所有长度为 t 的子串,看它的哈希值有没有出现过
    49         }
    50     return 0;
    51 }
    52 
    53 int main()
    54 {
    55 //    freopen ("POJ-2774.in", "r", stdin);
    56 //    freopen ("POJ-2774.out", "w", stdout);
    57     register int l,r,mid,ans;
    58     scanf ("%s%s",s,t);
    59     n = strlen(s), m = strlen(t);
    60     gethash ();
    61     l = 0, r = min(n,m);  //二分答案 注意要用 ans 记录答案,不能输出 l 或 r (可以被 hack 掉)
    62     while (l <= r)
    63         {
    64             mid = (l + r) >> 1;
    65             if (check (mid)) l = mid + 1, ans = mid;
    66             else r = mid - 1;
    67         }
    68     printf ("%d
    ",ans);
    69     return 0;
    70 }
  • 相关阅读:
    解决PyQt5在安装后无法找到Designer.exe问题,两个位置可供参考
    观察者模式
    策略模式
    模板方法模式(下)
    学过的技术容易忘,怎么办?
    Mysql主从配置
    Springboot处理CORS跨域请求
    SpringBoot学习2之注解简单配置Springboot+MyBatis
    Confluence7.4安装并破解汉化教程
    mysql json类型
  • 原文地址:https://www.cnblogs.com/y142857/p/7141783.html
Copyright © 2011-2022 走看看