HDU 5745 La Vie en rose(暴力碾压过去。。。)

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值