POJ 3167 Cow Patterns(模式串浮动匹配)

题目链接:http://poj.org/problem?id=3167

题意:模式串可以浮动的模式匹配问题给出模式串的相对大小,需要找出模式串匹配次数和位置。

思路:统计比当前数小,和于当前数相等的,然后进行kmp。

比如说模式串:1,4,4,2,3,1 而主串:5,6,2,10,10,7,3,2,9,那么2,10,10,7,3,2就是匹配的

code:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <vector>
 4 using namespace std;
 5 const int MAXN = 100005;
 6 const int MAXM = 25005;
 7
 8 int a[MAXN];        // 存放主串
 9 int b[MAXM];        // 存放模式串
10 int as[MAXN][30];   // as[i][j] = k表示0 - i位中有k个数字j
11 int bs[MAXM][30];   // bs[i][j] = k表示0 - i位中有k个数字j
12 int next[MAXM];     // 存放模式串失配时的移动位数
13 vector<int> ans;    // 存放结果
14 int n, m, s;
15
16 void Init()
17 {
18     ans.clear();
19     memset(as, 0, sizeof(as));
20     memset(bs, 0, sizeof(bs));
21     as[1][a[1]] = 1;
22     bs[1][b[1]] = 1;
23     for (int i = 2; i <= n; ++i)
24     {
25         memcpy(as[i], as[i - 1], sizeof(as[0]));
26         ++as[i][a[i]];
27     }
28     for (int i = 2; i <= m; ++i)
29     {
30         memcpy(bs[i], bs[i - 1], sizeof(bs[0]));
31         ++bs[i][b[i]];
32     }
33 }
34
35 void GetNext()
36 {
37     memset(next, 0, sizeof(next));
38     int i = 1, j = 0, k = 0;
39     next[1] = 0;
40     while (i <= m)
41     {
42         int si = 0, sj = 0, ei = 0, ej = 0;
43         for (k = 1; k < b[i]; ++k)
44             si += bs[i][k] - bs[i - j][k];
45         ei = bs[i][k] - bs[i - j][k];
46         for (k = 1; k < b[j]; ++k)
47             sj += bs[j][k];
48         ej = bs[j][k];
49         if (0 == j || (si == sj && ei == ej)) next[++i] = ++j;
50         else j = next[j];
51     }
52 }
53
54 void Kmp()
55 {
56     int i = 1, j = 1, k = 1;
57     while (i <= n)
58     {
59         int si = 0, sj = 0, ei = 0, ej = 0;
60         for (k = 1; k < a[i]; ++k)
61             si += as[i][k] - as[i - j][k];
62         ei = as[i][k] - as[i - j][k];
63         for (k = 1; k < b[j]; ++k)
64             sj += bs[j][k];
65         ej = bs[j][k];
66         if (0 == j || (si == sj && ei == ej)) ++i, ++j;
67         else j = next[j];
68         if (j == m + 1)
69         {
70             ans.push_back(i - m);
71             j = next[j];
72         }
73     }
74 }
75
76 int main()
77 {
78     while (scanf("%d %d %d", &n, &m, &s) == 3)
79     {
80         for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
81         for (int i = 1; i <= m; ++i) scanf("%d", &b[i]);
82         Init();
83         GetNext();
84         Kmp();
85         size_t len = ans.size();
86         printf("%d\n", len);
87         for (size_t i = 0; i < len; ++i) printf("%d\n", ans[i]);
88     }
89     return 0;
90 }
时间: 2024-10-09 23:30:09

POJ 3167 Cow Patterns(模式串浮动匹配)的相关文章

POJ 3461 Oulipo (求模式串在文本串中出现的次数)

Oulipo Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 36128   Accepted: 14584 Description The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter 'e'. He was a member of the Oulipo group. A quot

poj 1163 The Triangle &amp;poj 3167 Cow Bowling (dp)

链接:poj 1163 题意:输入一个n层的三角形,第i层有i个数,求从第1层到第n层的所有路线中,权值之和最大的路线. 规定:第i层的某个数只能连线走到第i+1层中与它位置相邻的两个数中的一个. 状态方程:f[i][j]=max(f[i-1][j-1],f[i-1][j])+a[i][j]; 1163代码: #include<stdio.h> #include<string.h> int a[105][105],f[105][105]; int max(int a,int b)

AC自动机 - AC自动机 - 多模式串的匹配运用 --- HDU 3065

病毒侵袭持续中 Problem's Link:http://acm.hdu.edu.cn/showproblem.php?pid=3065 Mean: 中文题,不解释. analyse: AC自动机的运用.这一题需要将模式串都存储下来,还有就是base的取值一定要弄清楚,由于这题的模式串都是大写字母所以我们可以通过剪枝来加速. Time complexity:o(n)+o(ml)  Source code: // Memory Time // 1347K 0MS // by : Snarl_js

【暖*墟】 #AC自动机# 多模式串的匹配运用

一.构建步骤 1.将所有模式串构建成 Trie 树 2.对 Trie 上所有节点构建前缀指针(类似kmp中的next数组) 3.利用前缀指针对主串进行匹配 AC自动机关键点一:trie字典树的构建过程 字典树的构建过程是这样的,当要插入许多单词的时候,我们要从前往后遍历整个字符串, 当我们发现当前要插入的字符其节点再先前已经建成,我们直接去考虑下一个字符即可, 当我们发现当前要插入的字符没有再其前一个字符所形成的树下没有自己的节点, 我们就要创建一个新节点来表示这个字符,接下往下遍历其他的字符.

【算法】AC自动机/AC算法 - 多模式串快速匹配

AC自动机 Accepted Aho-Corasick 性质 AC自动机/AC算法(Aho-Corasick automaton),是著名的多模式串匹配算法. 前置知识 字典树(重要) KMP算法(了解Next数组的作用) 典例与算法复杂度分析 典型例题是:给定一个主串 S,给定多个模式串 T,问主串 S 中存在多少个给定的模式串 在KMP算法中,一个长度为n的主串一个长度为m的模式串的复杂度为 O(n+m) 而如果直接照搬KMP算法到这种题型下,模式串处理一次就需要匹配一次 如果有t个模式串,

AC自动机 - 多模式串的匹配运用 --- HDU 2896

病毒侵袭 Problem's Link:http://acm.hdu.edu.cn/showproblem.php?pid=2896 Mean: 中文题,不解释. analyse: AC自动机的运用,多模式串匹配.就是有几个细节要注意,在这些细节上卡了半天了. 1)输出的网站编号和最终的病毒网站数不是一样的: 2)next指针要设128,不然会爆栈: 3)同理,char转换为int时,base要设为31: Time complexity:o(n)+o(ml)  Source code: // M

POJ 3189--Steady Cow Assignment【二分图多重匹配 &amp;&amp; 最大流求解 &amp;&amp; 枚举 &amp;&amp; 经典】

Steady Cow Assignment Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6023   Accepted: 2078 Description Farmer John's N (1 <= N <= 1000) cows each reside in one of B (1 <= B <= 20) barns which, of course, have limited capacity. So

【POJ 3167】Cow Patterns (KMP+树状数组)

Cow Patterns Description A particular subgroup of K (1 <= K <= 25,000) of Farmer John's cows likes to make trouble. When placed in a line, these troublemakers stand together in a particular order. In order to locate these troublemakers, FJ has lined

hdu2896 病毒侵袭 AC自动机入门题 N(N &lt;= 500)个长度不大于200的模式串(保证所有的模式串都不相同), M(M &lt;= 1000)个长度不大于10000的待匹配串,问待匹配串中有哪几个模式串,

/** 题目:hdu2896 病毒侵袭 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2896 题意:N(N <= 500)个长度不大于200的模式串(保证所有的模式串都不相同), M(M <= 1000)个长度不大于10000的待匹配串,问待匹配串中有哪几个模式串, 题目保证每个待匹配串中最多有三个模式串. 思路:ac自动机做法,字符为可见字符,那么直接就是他们的ascii值作为每一个字符的标志.最多128: 由于不超过三个,所以找到3个就可以re