Problem A SPOJ SUB_PROB

Description

String Matching is an important problem in computer science research and finds applications in Bioinformatics, Data mining,pattern recognition, Internet security and many more areas.

The problem we consider here is a smaller version of it. You are given a string M and N other strings smaller in length than M. You have to find whether each of these N strings is a substring of M. All strings consist of only alphanumeric characters.

You are required to write a C/CPP code to solve the problem.

Input

Input to the program consists of a series of lines. The first line contains the string M (no more than 100000 characters long). The next line contains an integer N (<1000) the number of query strings. Each of the next N lines contain a string S (each of which is no more than2000 characters long).

Output

Output should consist of N lines each with a character ‘Y‘/‘N‘ indicating whether the string S is a substring of String M or not.

Sample Input

Input:
abghABCDE2abABab

Output: 
NY

Note: The test data for this problem not only consist of the official test cases from the contest,as well some cases of my own.

A testcase is added on 25.7.2010,after rejudging 3 users loose accepted.

•题意: 给定一个长为M(M≤100000 )的文本串,和N(N≤1000)个长度不超过2000的模式串,问每个模式串是否在文本串中出现过?

•几乎和周一课件上的第一个例题一模一样。。

•把文本串丢到AC自动机里面去跑。

•1.可能有两个相同的模式串(略坑吧。)

•2.一个模式串可能是另一个模式串的后缀,即如果一个点的fail指针指向的点是一个“危险节点”,那么它本身也是一个“危险节点”。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 1000050 ;
const int sigma_size = 52 ;

int ID[1010] , tot ;
char text[100050] , word[2111] ;
bool flag[1010] ;
int son[maxn][sigma_size] , val[maxn] , f[maxn] , last[maxn] , q[maxn], sz ;

inline int idx(char c) {
    if(c<=‘Z‘) return c - ‘A‘ ;
    else return c - ‘a‘ + 26 ;
}

int Insert(char *s){
    int u = 0 ;
    for(int i=0 ; s[i] ; i++) {
        int v = idx(s[i]) ;
        if(!son[u][v]) son[u][v] = ++sz ;
        u = son[u][v] ;
    }
    if(!val[u]) val[u] = ++tot ;
    return val[u];
}

void get_fail() {
    int rear = 0 ;
    f[0] = 0 ;
    for(int c=0; c<sigma_size ; c++) {
        int u = son[0][c] ;
        if(u) f[u] = last[u] = 0 , q[rear++] = u ;
    }
    for(int _i=0; _i<rear ; _i++) {
        int u = q[_i] ;
        for(int c=0; c<sigma_size; c++){
            int v = son[u][c] ;
            if(!v) { son[u][c] = son[f[u]][c] ; continue ; }
            q[rear++] = v;
            int x = f[u] ;
            while(x && !son[x][c]) x = f[x] ;
            f[v] = son[x][c] ;
            last[v] = val[f[v]] ? f[v] : last[f[v]] ;
        }
    }
}

void print(int u){
    while(u) {
        flag[val[u]] = true ;
        u = last[u] ;
    }
}

void Find(char *s){
    int j = 0;
    for(int i=0; s[i] ; i++) {
        int c=idx(s[i]);
        while(j && !son[j][c]) j = f[j] ;
        j = son[j][c] ;
        print(j) ;
    }
}

int main()
{
    gets(text) ;
    int n ;
    scanf("%d", &n) ; getchar() ;
    for(int i=1; i<=n; i++) {
        scanf("%s" , word) ;
        ID[i] = Insert(word);
    }
    Find(text) ;
    for(int i=1; i<=n; i++) {
        if(flag[ ID[i] ]) puts("Y") ;
        else puts("N") ;
    }
    return 0 ;
}

  

Problem A SPOJ SUB_PROB

时间: 2024-10-21 22:40:37

Problem A SPOJ SUB_PROB的相关文章

Problem B SPOJ DCEPC11I

Description Vaibhav Sir and Saikat Sir, after completing their graduation, got a job together at a store. Their boss at the store was Sidharth Sir, who was very strict and did not want anyone to have fun at the job. He gave Vaibhav and Saikat sir a v

Problem E SPOJ ROCK

Description A manufacturer of sweets has started production of a new type of sweet called rock. Rock comes in sticks composed of one-centimetre-long segments, some of which are sweet, and the rest are sour. Before sale, the rock is broken up into sma

CSU-ACM暑假集训基础组训练赛(4)解题报告

•Problem A SPOJ SUB_PROB   AC自动机 •题意: 给定一个长为M(M≤100000 )的文本串,和N(N≤1000)个长度不超过2000的模式串,问每个模式串是否在文本串中出现过? •几乎和周一课件上的第一个例题一模一样.. •把文本串丢到AC自动机里面去跑. •注意: •1.可能有两个相同的模式串(略坑吧.) •2.一个模式串可能是另一个模式串的后缀,即如果一个点的fail指针指向的点是一个“危险节点”,那么它本身也是一个“危险节点”. 1 #include <ios

SPOJ GNYR09F 数字上的找规律DP

Problem C      SPOJ GNYR09F dp题,dp可能刚刚开始对大家来说比较难,但是静下心来分析还是比较简单的: dp(i ,j ,k)表示前i个数中,当前累积和为j,末尾数字为k的方案数. 考虑第i个位置的2种情况: 1.放0:dp(i,j,0) = dp(i-1,j,0) + dp(i-1,j,1) 2.放1:dp(i,j,1)= dp(i-1,j,0) 因为每一行最开始的状态均从i=j+1,dp(i,j,0)=0,dp(i,j,1)=1开始的,但因为这样子开头均为1,那些

Spoj PRIME1 - Prime Generator

题意翻译 求给定的两个数之间的素数 Translated by @kaiming 题目描述 Peter wants to generate some prime numbers for his cryptosystem. Help him! Your task is to generate all prime numbers between two given numbers! 输入输出格式 输入格式: The input begins with the number t of test cas

暑假集训-个人赛第四场

ID Origin Title   10 / 52 Problem A SPOJ AMR10A Playground     Problem B SPOJ AMR10B Regex Edit Distance     Problem C SPOJ AMR11C Robbing Gringotts   1 / 14 Problem D SPOJ AMR10D Soccer Teams   0 / 3 Problem E SPOJ AMR10E Stocks Prediction   17 / 19

数论十题

数论十题 Problem Zero:[neerc2011]Gcd guessing game 现在有一个数x,1 ≤ x≤ n,告诉你n,每次你可以猜一个数y,如果x==y则结束,否则返回gcd(x,y),问最少只要几次就可以保证猜出答案. 本题纯属娱乐.仅仅是一个GCD的游戏,跑题了. 因为本题要求最坏情况,我们直观地猜想就是每次返回都是1.由于答案有可能是质数,而判定一个数,必须要把含有这个质因子的数问一遍.于是,我们引出这样一个思路,将所有1-n的质数分组,每组的积<=n,答案就是组数.

CSU-ACM暑假集训基础组七夕专场

•Problem A Codeforces 20C       最短路(dij,spfa) •题意:给出一张n个点m条边的无向图 (2 ≤ n ≤ 105, 0 ≤ m ≤ 105),输出从1到n的任意一条最短路径. •解法:dijkstra或者spfa,用pre数组记录到达每个点最短距离的前驱结点. •注意:路径的长度范围是 1 ≤ wi ≤ 106,从1到n的最短路径长度可能超出int范围. •没有路径从1到达n时要输出-1 1 #include <cstdio> 2 #include &

周一训练赛题解

这次完全是水题大集合啊,希望大家A的开心: 前两个题是我找的,后两个是陶叔找的,另外因为我的偷懒,下面所有的代码都是陶叔亲自写的,十分感谢陶叔: 陶叔暑假为了大家的集训,牺牲了很多自己宝贵的时间,大家接下来要好好训练啊!!!! 废话少说,进入正题: Problem A      SPOJ QUEST5 签到题: 将所有的边按照右端点排个序,然后每次选择没有钉住的点,然后把这之后的所有与它相交的边全去掉: 代码: #include <cstdio> #include <cstring>