• hdu 5972 Regular Number 字符串Shift-And算法 + bitset


    题目链接

    题意

    给定两个串(S,T),找出(S)中所有与(T)匹配的子串。

    这里,(T)的每位上可以有若干((leq 10))种选择,匹配的含义是:对于(S)的子串的每一位,(T)的相应位都有一种选择与之对应。

    题解

    shift-and算法详解 https://www.douban.com/note/321872072/

    搜出来的题解全都是(shift-and)的...。

    学习了一波...然而并不明白(kmp)为什么不可以...。

    看到这道题直觉就是和hdu 4749一样美滋滋写了然后(T)了...。

    Code

    #include <bits/stdc++.h>
    #define maxn 1010
    #define maxm 5000010
    using namespace std;
    typedef long long LL;
    char s[maxm];
    bitset<maxn> B[11];
    const int BUF_SIZE = (int)1e4+10;
    namespace fastIO{
        #define BUF_SIZE 100000
        #define OUT_SIZE 1000000
        bool IOerror=0;
        inline char nc(){
            static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
            if(p1==pend){
                p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);
                if (pend==p1){IOerror=1;return -1;}
            }return *p1++;
        }
        inline bool blank(char ch){return ch==' '||ch=='
    '||ch=='
    '||ch=='	';}
        inline int read(char *s){
            char ch=nc();
            for(;blank(ch);ch=nc());
            if(IOerror)return 0;
            for(;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
            *s=0;
            return 1;
        }
        inline int RI(int &a){
            char ch=nc(); a=0;
            for(;blank(ch);ch=nc());
            if(IOerror)return 0;
            for(;!blank(ch)&&!IOerror;ch=nc())a=a*10+ch-'0';
            return 1;
        }
        struct Ostream_fwrite{
            char *buf,*p1,*pend;
            Ostream_fwrite(){buf=new char[BUF_SIZE];p1=buf;pend=buf+BUF_SIZE;}
            void out(char ch){
                if (p1==pend){
                    fwrite(buf,1,BUF_SIZE,stdout);p1=buf;
                }*p1++=ch;
            }
            void flush(){if (p1!=buf){fwrite(buf,1,p1-buf,stdout);p1=buf;}}
            ~Ostream_fwrite(){flush();}
        }Ostream;
        inline void print(char x){Ostream.out(x);}
        inline void println(){Ostream.out('
    ');}
        inline void flush(){Ostream.flush();}
        char Out[OUT_SIZE],*o=Out;
        inline void print1(char c){*o++=c;}
        inline void println1(){*o++='
    ';}
        inline void flush1(){if (o!=Out){if (*(o-1)=='
    ')*--o=0;puts(Out);}}
        struct puts_write{
            ~puts_write(){flush1();}
        }_puts;
    };
    int n, cnt[maxn], a[maxn][11];
    void GetDict() {
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < cnt[i]; ++j) {
                B[a[i][j]][i] = 1;
            }
        }
    }
    void work() {
        for (int i = 0; i < n; ++i) {
            fastIO::RI(cnt[i]);
            for (int j = 0; j < cnt[i]; ++j) fastIO::RI(a[i][j]);
        }
        GetDict();
        fastIO::read(s);
        int len = strlen(s);
        bitset<maxn> D;
        for (int i = 0; i < len; ++i) {
            D <<= 1; D[0] = 1;
            D &= B[s[i]-'0'];
            if (D[n-1]) {
                char temp = s[i+1]; s[i+1] = '';
                printf("%s
    ", s+i-n+1);
                s[i+1] = temp;
            }
        }
    }
    int main() {
        while (fastIO::RI(n)) work();
        return 0;
    }
    
    

    TLE Code kmp Ver.

    #include <bits/stdc++.h>
    #define maxn 1010
    #define maxm 5000010
    char s[maxm];
    int b[maxm];
    int a[maxn][11], cnt[maxn], f[maxn];
    using namespace std;
    typedef long long LL;
    int n, m;
    bool match1(int x, int y) {
        for (int i = 0; i < cnt[x]; ++i) {
            for (int j = 0; j < cnt[y]; ++j) {
                if (a[x][i] == a[y][j]) return true;
            }
        }
        return false;
    }
    void getfail() {
        f[0] = f[1] = 0;
        for (int i = 1; i < n; ++i) {
            int j = f[i];
            while (j && !match1(i, j)) j = f[j];
            f[i+1] = match1(i, j) ? j+1 : 0;
        }
    }
    bool match2(int x, int y) {
        for (int i = 0; i < cnt[y]; ++i) {
            if (b[x] == a[y][i]) return true;
        }
        return false;
    }
    void kmp() {
        int j = f[1];
        for (int i = 1; i < m; ++i) {
            while (j && !match2(i, j)) j = f[j];
            if (match2(i, j)) ++j;
            if (j == n) {
                for (int k = i-n+1; k <= i; ++k) putchar('0'+b[k]);
                putchar('
    ');
            }
        }
    }
    void work() {
        for (int i = 0; i < n; ++i) {
            scanf("%d", &cnt[i]);
            for (int j = 0; j < cnt[i]; ++j) scanf("%d", &a[i][j]);
        }
        getfail();
        scanf("%s", s);
        m = strlen(s);
        for (int i = 0; i < m; ++i) b[i] = s[i]-'0';
        kmp();
    }
    int main() {
        while (scanf("%d", &n) != EOF) work();
        return 0;
    }
    
  • 相关阅读:
    EasyUI datagrid 的多条件查询
    js将时间戳转换为日期类型
    js限制字符串长度,超出的部分补...
    js打印WEB页面内容代码大全
    js倒计时一分钟
    java获取上个星期第一天和最后一天
    两个Html页面之间值得传递
    jS处理中英文时间格式化问题
    JS获取当月第一天和最后一天
    Java 计算两个日期相差月数、天数
  • 原文地址:https://www.cnblogs.com/kkkkahlua/p/7680373.html
Copyright © 2020-2023  润新知