Problem Description
Professor Zhang would like to solve the multiple pattern matching problem, but he only has only one pattern string p=p1p2...pm. So, he wants to generate as many as possible pattern strings from p using the following method:
1. select some indices i1,i2,...,ik such that 1≤i1<i2<...<ik<|p| and |ij−ij+1|>1 for all 1≤j<k.
2. swap pij and pij+1 for all 1≤j≤k.
Now, for a given a string s=s1s2...sn, Professor Zhang wants to find all occurrences of all the generated patterns in s.
Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first line contains two integers n and m (1≤n≤105,1≤m≤min{5000,n}) -- the length of s and p.
The second line contains the string s and the third line contains the string p. Both the strings consist of only lowercase English letters.
Outpu
For each test case, output a binary string of length n. The i-th character is "1" if and only if the substring sisi+1...si+m−1 is one of the generated patterns.
Sample Input
3
4 1
abac
a
4 2
aaaa
aa
9 3
abcbacacb
abc
Sample Output
1010
1110
100100100
这个题在当时做的时候是万万没想到可以直接暴力的。。后来抱着试试的心态写了一发居然过了。。人生啊。。。
直接对每一个长度为m的子串进行对比,设当前位置为i:
如果子串与p串中i位置字符相同 或 子串与p串中i与i+1两个位置的字符组成相同,继续往后扫;
一旦不满足上述要求的情况发生,停止扫描,将这个子串在s串中的起点位置标记为0;
若整个子串都满足第一条,将这个子串在s串中的起点位置标记为1;
代码:(跑了5000多ms,为了省事用的string,改成char[]和scanf什么的会快很多)
#include<bits/stdc++.h>
using namespace std;
string s,p;
char ans[500005];
void check(int n,int m){
int idx, flag;
string tmp;
for(int i = 0; i <= n-m; i++){
tmp = s.substr(i,m);
idx = 0, flag = 1;
while(idx < m && flag){
if(tmp[idx] == p[idx])
idx++;
else if(idx < m-1 && tmp[idx] == p[idx+1] && tmp[idx+1] == p[idx])
idx += 2;
else
flag = 0;
}
ans[i] = ((idx>=m) && flag) ? '1' : '0';
}
ans[n] = '\0';
}
int main(){
int t, n, m;
cin >> t;
while(t--){
memset(ans,'0', sizeof(ans));
cin >> n >> m;
cin >> s >> p;
check(n,m);
cout << ans << endl;
}
return 0;
}