Ural 1732. Ministry of Truth 多串匹配KMP

1732. Ministry of Truth

Time limit: 1.0 second
Memory limit: 64 MB
In whiteblack on blackwhite is written the utterance that has been censored by the Ministry of Truth. Its author has already disappeared along with his whole history, and now, while Big Brother is watching somebody else, you, as an ordinary official of the Minitrue, have to delete some letters from the utterance so that another utterance will appear, which has been approved of by the Ministry.
The Ministry of Truth defines a  word as a nonempty sequence of English letters and an  utterance as a sequence of one or more words separated with one or more spaces. There can also be spaces before the first word and after the last word of an utterance. In order to compare two utterances, one should delete all the leading and trailing spaces and replace each block of consecutive spaces with one space. If the resulting strings coincide, then the utterances are considered to be equal. When the official deletes a letter from the utterance, this letter turns into a space.

Input

The first line contains the original utterance and the second line contains the utterance that must be obtained. The length of each utterance is at most 100000 symbols. The words in both utterances are separated with exactly one space; there are no leading or trailing spaces in each line. The original and the required utterances are different.

Output

If you can't carry out your order, output “I HAVE FAILED!!!” in the only line. Otherwise, output the original utterance replacing the letters that are to be deleted with the underscore character.

Samples

input output
Preved to Medved
Preved Me
Preved __ Me____
this is impossible
im possible
I HAVE FAILED!!!
Problem Author: Alex Samsonov (prepared by Dmitry Ivankov)
Problem Source: XIV Open USU Championship
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int maxn = 100010;
int n;
char s[maxn], t[maxn];
int p[maxn];
bool mark[maxn];
bool kmp(char *T, char *P, int N, int M)
{
    int i, j;
    p[0] = j = -1;
    for (i = 1; i < M; i++)
    {
        while (j > -1 && P[j + 1] != P[i]) j = p[j];
        if (P[j + 1] == P[i]) j++;
        p[i] = j;
    }
    j = -1;
    for (i = 0; i < N; i++)
    {
        while (j > -1 && P[j + 1] != T[i]) j = p[j];
        if (P[j + 1] == T[i]) j++;
        if (j == M - 1)
        {
            for (int k = i + n; k >= i - M + 1 + n; --k)
                mark[k] = 1;
            n += i + 2;
            return true;
        }
    }
    return false;
}
int main()
{
    char c;
    bool flag = 1;
    gets(s);
    n = 0;
    int ls = strlen(s);
    while (scanf("%s", t))
    {
        c = 0;
        scanf("%c", &c);
        if (flag)
        {
            if (!kmp(s + n, t, ls - n, strlen(t)))
            {
                flag = 0;
                break;
            }
            if (n >= ls) break;
        }
        if (c != ' ') break;
    }
    if (!flag) puts("I HAVE FAILED!!!");
    else
    {
        for (int i = 0; i < ls; i++)
            if (s[i] == ' ') putchar(s[i]);
            else if (!mark[i]) printf("_");
            else printf("%c", s[i]);
        printf("\n");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值