HDU-5972 Regular Number (Shift-And字符串匹配)

题目链接:HDU-5972 Regular Number

题意

模式串第 \(i\) 个位置可以有 \(a_i\) 个字符满足要求,给出这 \(a_i\) 个字符。给出一个主串,输出主串中所有能与模式串匹配的子串。


思路

Shift-And 算法:学习传送门

Shift-And 算法基本上也只适用这种给出模式串字母表的情况,因模式串有太多种可能而不能用 kmp 算法,这道题就是根据 Shift-And 的解法特性来出的。时间复杂度 \(O(nm/x)\)\(n\) 为主串长度,\(m\) 为模式串长度,\(x\) 为计算机的位数。


代码实现

#include <cstdio>
#include <bitset>
using std::bitset;
bitset<1010> b[11], D;  // b[i][j]=1表示i这个值可以放在模式串的第j个位置
char s[5000010];

int main() {
    int n;
    while (~scanf("%d", &n)) {
        for (int i = 0; i < 11; i++) b[i].reset();
        D.reset();
        for (int i = 0, nn, x; i < n; i++) {
            scanf("%d", &nn);
            while (nn--) {
                scanf("%d", &x);
                b[x].set(i);
            }
        }
        getchar();
        fgets(s, 5000005, stdin);
        for (int i = 0; s[i]; i++) {
            D <<= 1;
            D.set(0);
            D &= b[s[i]-'0'];
            if (D[n-1]) {
                char tmp = s[i+1];
                s[i+1] = '\0';
                puts(s + i-n+1);
                s[i+1] = tmp;
            }
        }
    }
    return 0;
}
posted @ 2020-06-07 16:19  _kangkang  阅读(132)  评论(0编辑  收藏  举报