POJ3167 Cow Patterns (KMP)

原创 2015年07月09日 19:29:24

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 up his N (1 <= N <= 100,000) cows. The cows will file past FJ into the barn, staying in order. FJ needs your help to locate suspicious blocks of K cows within this line that might potentially be the troublemaking cows. 

FJ distinguishes his cows by the number of spots 1..S on each cow's coat (1 <= S <= 25). While not a perfect method, it serves his purposes. FJ does not remember the exact number of spots on each cow in the subgroup of troublemakers. He can, however, remember which cows in the group have the same number of spots, and which of any pair of cows has more spots (if the spot counts differ). He describes such a pattern with a sequence of K ranks in the range 1..S. For example, consider this sequence: 

      1 4 4 3 2 1
In this example, FJ is seeking a consecutive sequence of 6 cows from among his N cows in a line. Cows #1 and #6 in this sequence have the same number of spots (although this number is not necessarily 1) and they have the smallest number of spots of cows #1..#6 (since they are labeled as '1'). Cow #5 has the second-smallest number of spots, different from all the other cows #1..#6. Cows #2 and #3 have the same number of spots, and this number is the largest of all cows #1..#6. 

If the true count of spots for some sequence of cows is: 

 5 6 2 10 10 7 3 2 9
then only the subsequence 2 10 10 7 3 2 matches FJ's pattern above. 

Please help FJ locate all the length-K subsequences in his line of cows that match his specified pattern.

Input

Line 1: Three space-separated integers: N, K, and S 

Lines 2..N+1: Line i+1 describes the number of spots on cow i. 

Lines N+2..N+K+1: Line i+N+1 describes pattern-rank slot i.

Output

Line 1: The number of indices, B, at which the pattern matches 

Lines 2..B+1: An index (in the range 1..N) of the starting location where the pattern matches.

Sample Input

9 6 10
5
6
2
10
10
7
3
2
9
1
4
4
3
2
1

Sample Output

1
3

Hint

Explanation of the sample: 

The sample input corresponds to the example given in the problem statement. 

There is only one match, at position 3 within FJ's sequence of N cows.

Source

USACO 2005 December Gold


#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int MAXN = 100010;
const int MAXM = 25010;
int a[MAXN];
int b[MAXN];
int n, m, s;
int as[MAXN][30];
int bs[MAXM][30];

void init() { //预处理,计算当前数包含多少相同值的数 (s<=25,所以这里直接开了数组计算)
    for(int i = 0; i < n; ++i) {
        if(i ==0) {
            for(int j = 1; j <= 25; ++j) as[i][j] = 0;
        } else {
            for(int j = 1; j <= 25; ++j) as[i][j] = as[i-1][j];
        }
        as[i][a[i]]++;
    }
    for(int i = 0; i < m; ++i) {
        if(i ==0) {
            for(int j = 1; j <= 25; ++j) bs[i][j] = 0;
        } else {
            for(int j = 1; j <= 25; ++j) bs[i][j] = bs[i-1][j];
        }
        bs[i][b[i]]++;
    }
}

int next[MAXM];
void kmp_pre() {
    int i, j;
    j = next[0] = -1;
    i = 0;
    while(i < m) {
        int t11 = 0, t12 = 0, t21 = 0, t22 = 0;
        for(int k = 1; k < b[i]; k++) { //比b[i]小的数有多少
            if(i-j > 0) t11 += bs[i][k] - bs[i-j-1][k];
            else t11 += bs[i][k];
        }
        if(i-j > 0) t12 = bs[i][b[i]] - bs[i-j-1][b[i]];  //等于b[i]的数有多少
        else t12 = bs[i][b[i]];

        for(int k = 1; k < b[j]; k++) {  //比b[j]小的数有多少
            t21 += bs[j][k];
        }
        t22 = bs[j][b[j]];  //等于b[j]的数有多少
        if(j == -1 || (t11 == t21 && t12 == t22)) {
            next[++i] = ++j;
        } else {
            j = next[j];
        }
    }
}

vector<int>ans;
void kmp() {
    ans.clear();
    int i, j;
    kmp_pre();
    i = j = 0;
    while(i < n) {
        int t11 = 0, t12 = 0, t21 = 0, t22 = 0;
        for(int k = 1; k < a[i]; k++) {
            if(i-j > 0) t11 += as[i][k] - as[i-j-1][k];
            else t11 += as[i][k];
        }
        if(i-j > 0) t12 = as[i][a[i]] - as[i-j-1][a[i]];
        else t12 = as[i][a[i]];

        for(int k = 1; k < b[j]; k++) {
            t21 += bs[j][k];
        }
        t22 = bs[j][b[j]];
        if(j == -1 || (t11 == t21 && t12 == t22)) { //两个位置的数具有同等偏向关系取决于两个数的 比自身值小 和 等于自身值 这两个量相等
            i++; j++;
            if(j >= m) {
                ans.push_back(i-m+1);
                j = next[j];
            }
        } else {
            j = next[j];
        }
    }
}

int main()
{
    //freopen("out.txt", "w", stdout);
    //freopen("in.txt", "r", stdin);
    while(scanf("%d%d%d", &n, &m, &s) == 3) {
        for(int i = 0; i < n; ++i) scanf("%d", &a[i]);
        for(int i = 0; i < m; ++i) scanf("%d", &b[i]);
        init();
        kmp();
        printf("%d\n", ans.size());
        for(int i = 0; i < ans.size(); ++i) {
            printf("%d\n", ans[i]);
        }
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

poj 3167 Cow Patterns ... 四种算法 (均结合kmp)

题目链接:http://poj.org/problem?id=3167 第1,2种算法思路是一样的,但是实现方法不同。 算法归于以下结论:两个序列的偏序相同则两序列同一位以前小于它和等于它...

poj 3167 Cow Patterns (kmp + 线段树/树状数组)

这道题确实让我更加深入的了解了kmp。。。。 以前的匹配只要字符或者是数值一样就可以,这道题是区间名次一样进行匹配的。 一个数在区间中的名次可以转化为,它前面比他小的数的个数,和他相等的个数,和比...

POJ-3167- Cow Patterns(KMP)

Cow Patterns Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4184   A...

pku 3167 Cow Patterns(kmp)

Cow Patterns Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 2610   A...

POJ 3167 Cow Patterns

题目链接:http://poj.org/problem?id=3167Description约翰的N(1≤N≤100000)只奶牛中出现了K(1≤K≤25000)只爱惹麻烦的坏蛋。奶牛们按一定的顺序排...

POJ 3167 Cow Patterns

kmp + 树状数组。树状数组动态更新排名。明白了方法以后,细节方面调了半天。。。想吐了。。。逗b的地方也不想改了。注意代码中注释的地方。 真的要想清楚再写,不然很浪费时间。 #include #i...

kmp poj 3167

参考了这个http://www.cppblog.com/zxb/archive/2010/10/06/128782.aspx?opt=admin 他用的是hash的思想 题目大意是:给一个字符串,...

POJ3167 KMP

写到这里KMP应该马马虎虎算懂了。。。觉得这道题难点不在KMP上,并且很惭愧,难得那个点不是自己想出来的 #include #include #include #include #include...

北大POJ3176-Cow Bowling

  • 2012年05月11日 02:28
  • 793B
  • 下载

POJ3176-Cow Bowling

  • 2011年07月31日 22:55
  • 8KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ3167 Cow Patterns (KMP)
举报原因:
原因补充:

(最多只允许输入30个字)