codeforces MUH and Cube Walls

题意:给定两个序列a ,b, 如果在a中存在一段连续的序列使得
a[i]-b[0]==k, a[i+1]-b[1]==k.... a[i+n-1]-b[n-1]==k
就说b串在a串中出现过!最后输出b串在a串中出现几次!

思路: KMP变形!如何转换成KMP求解呢?
举一个例子说明一下:
a: 5 10 8 10 11 9 11 12 10 15
b: 4 2 4 5 3
根据题意 a中的 10 8 10 11 9 与 b是匹配的, 11 9 11 12 10跟b也是匹配的!
如何将b串以及 10 8 10 11 9, 以及 11 9 11 12 10转换成同一个串?这样好套用kmp啊!
因为对应的数值的差值都是相同的! 令a[i]-=a[i+1], b[i]-=b[i+1]!
这样也就是将串的长度减少了1,这样就可以套kmp模板了!
别忘记对特殊情况考虑一下!

 1 #include<iostream>
 2 #include<cmath>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<cstring>
 6 #define N 200005
 7 using namespace std;
 8
 9 int f[N], a[N], b[N];
10 int n, w;
11 void getFail(){
12     f[0]=0; f[1]=0;
13     for(int i=1; i<w; ++i){
14         int j=f[i];
15         while(j && b[i] != b[j]) j=f[j];
16         if(b[i] == b[j]) f[i+1] = j+1;
17         else f[i+1] = 0;
18     }
19 }
20
21 void findText(){
22     int j=0;
23     int cnt = 0;
24     for(int i=0; i<n; ++i){
25         while(j && a[i] != b[j])  j=f[j];
26         if(a[i] == b[j]) ++j;
27         if( j == w ) ++cnt;
28     }
29     printf("%d\n", cnt);
30 }
31
32 int main(){
33     scanf("%d%d", &n, &w);
34     for(int i=0; i<n; ++i){
35         scanf("%d", &a[i]);
36         if(i) a[i-1] -= a[i];
37     }
38
39     for(int i=0; i<w; ++i){
40         scanf("%d", &b[i]);
41         if(i) b[i-1] -= b[i];
42     }
43     if(n==1 && w==1){
44         printf("%d\n", 1);
45         return 0;
46     }
47     else if(n==1){
48         printf("%d\n", 0);
49         return 0;
50     }
51     else if( w==1 ){
52         printf("%d\n", n);
53         return 0;
54     }
55     --n;
56     --w;
57     b[w] = -1e6;
58     getFail();
59     findText();
60     return 0;
61 }

时间: 2024-07-28 12:40:56

codeforces MUH and Cube Walls的相关文章

Codeforces Round #269 (Div. 2) D. MUH and Cube Walls KMP

D. MUH and Cube Walls Polar bears Menshykov and Uslada from the zoo of St. Petersburg and elephant Horace from the zoo of Kiev got hold of lots of wooden cubes somewhere. They started making cube towers by placing the cubes one on top of the other. T

D - MUH and Cube Walls

D. MUH and Cube Walls Polar bears Menshykov and Uslada from the zoo of St. Petersburg and elephant Horace from the zoo of Kiev got hold of lots of wooden cubes somewhere. They started making cube towers by placing the cubes one on top of the other. T

CodeForces - 471D MUH and Cube Walls

CodeForces - 471D 记录差分,利用kmp对分别除去了第一个数的两个数组进行匹配 注意特判模式串长度为一的情况 1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 5 const int maxn = 2e5 + 10; 6 int ans, n, m; 7 8 void find_substring(int pattern[], int text[]) { 9 vector<int

【CodeForces】471D MUH and Cube Walls KMP或者字符串HASH

想到两点就行: 1.相邻项相减,处理出相对高度,这样如果pattern或者text增加的话,就没问题了 2.KMP匹配O(n) HASH的话 ,我WA在第25组数据了,听说如果改为大素数取模就能AC KMP AC了 但是好奇怪我的KMP模板难道有问题?? 先贴KMP ac 代码 //#pragma comment(linker, "/STACK:102400000,102400000") #include <cstdio> #include <cstring>

#269(div2) D. MUH and Cube Walls

题意:2个序列A,B,B可以自身全部加减某个数字,问B和A匹配的个数 思路:不管怎样,B序列中相邻2个数之间的差是不变的,然后KMP. 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=200005; 4 5 int aa[N],a[N]; 6 int bb[N],b[N]; 7 int n,m; 8 int Next[N]; 9 10 void getnext() 11 { 12 int j, k; 13 j = 0

Codeforces 464B Restore Cube(暴力)

题目链接:Codeforces 464B Restore Cube 题目大意:给定8个点坐标,对于每个点来说,可以随意交换x,y,z坐标的数值.问说8个点是否可以组成立方体. 解题思路:直接暴力枚举即可,保证一个点的坐标不变,枚举量为67,将上一层判断. #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; typedef

CodeForces 525D Arthur and Walls

广搜.看了官方题解才会的..... 定义2*2的小矩阵,有三个是点,一个是星,这样的小矩阵被称为元素块. 首先把所有元素块压入队列,每次取出对头,检查是否还是元素块,如果是 那么将那个*改为点,否则跳过 改完之后,检查周围8个点是否是元素块,如果有新产生的元素块,那么压入队列. 这样操作完之后就是答案. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include&l

codeforces D - Arthur and Walls

这题说的是给了一个矩阵,必须让.连接起来的图形变成矩形,2000*2000的矩形,那么我们就可以知道了,只要是存在一个有点的区域应该尽量将他削为矩形,那么将这个图形进行缩放,最后我们知道只要存在一个2*2 的矩形中有1个是*就必须将这个*号去掉. 采用bfs去做 1 #include <iostream> 2 #include <algorithm> 3 #include <string.h> 4 #include <cstdio> 5 #include &

7月好题记录

Codeforces 1063 B. Labyrinth [确定性]给出一个迷宫\((1 \leq n,m \leq 2000)\),求从起点到各个点,能够做到在左移动次数不超过\(x\)次,右移动次数不超过\(y\)次的情况下到达的点的个数. 显然贪心地要求到达每个点时左右移动次数越少越好,但是两个关键字很难维护.而事实上,起点终点确定时,左移动次数确定时右移动次数一定确定.当终点在起点左侧时,最小化左移动次数即可:当终点在起点右侧时,依然最小化左移动次数即可.当然两者都最小化右移动次数也可以