hdu5745(dp+bitset)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5745

C++ bitset的用法:https://www.cnblogs.com/magisk/p/8809922.html

题目:

题意:给两个字符串 a 和 b ,b可以进行变换,规则是可以任意交换相邻两个字符的位置,但是不可以有交叉。求a中每一个位置能不能匹配b或b变换得到的子串。

思路:dp,dp[i]表示匹配模式串前i+1个的状况,其中dp[i][0],dp[i][1],dp[i][2]分别表示和前一个交换,不交换,和后一个交换的情况,采用bitset优化。

 代码:

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<bitset>
using namespace std;
bitset<100005>dp[2][3],w[26];
char s[100005];
char t[5005];
int main()
{
    int tt;
    int n,m;
    scanf("%d",&tt);
    while(tt--)
    {
        scanf("%d%d",&n,&m);
        scanf("%s%s",s,t);
        for(int i=0;i<26;i++)w[i].reset();//由bitset知,reset函数不带参数时将bitset的每一位置为0
        for(int i=0;i<2;i++)
            for(int j=0;j<3;j++)
                dp[i][j].reset();
        for(int i=0;i<n;i++)
        {
            w[s[i]-'a'][i]=1;
        }
        dp[0][1]=w[t[0]-'a'];
        if(m>1)dp[0][2]=w[t[1]-'a'];
        int now = 0;
        for(int i=1;i<m;i++)
        {
            now^=1;
            dp[now][0]=(dp[now^1][2]<<1)&w[t[i-1]-'a'];
            dp[now][1]=((dp[now^1][1]|dp[now^1][0])<<1)&w[t[i]-'a'];
            if(i<m-1)
            {
                dp[now][2]=((dp[now^1][1]|dp[now^1][0])<<1)&w[t[i+1]-'a'];
            }
        }
        for(int i=0;i<n;i++)
        {
            if(dp[now][0][i+m-1]||dp[now][1][i+m-1])printf("1");
            else printf("0");
        }
        puts("");
    }
}

 

posted @ 2019-03-01 19:28  里昂静  阅读(320)  评论(0编辑  收藏  举报