关闭

[JZOJ3427]【NOIP2013模拟】归途与征程

229人阅读 评论(0) 收藏 举报
分类:

Description

这里写图片描述

Solution

注意,这里的匹配是全部都要匹配,不能落下一个字符。

A串中,”* “将字符串分成若干个区间(不包括”*”)。
bz[i][j]表示A串中第i个区间和B串中第j位开头能否匹配
对于每一个区间,都与B串做一次KMP,可以在O(NM)的时间范围内求出bz

然后我们只需要把B串复制一遍,再枚举开头判断就好。

但是这样判断的复杂度达到O(M),总的是O(M2)

考虑优化判断。

于是可以预处理next[i][j]表示bz[i+1][k]=1大于jk最小值

这样复杂度就变成O(NM)

Code

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fod(i,a,b) for(i=a;i>=b;i--)
using namespace std;
int n,m,m1,num,a[101],next[101][200001];
char s1[101],s2[200001];
bool bz[101][200001];
void kmp(int ar,int lt,int rt)
{
    if (rt<lt)
    {
        int i;
        fo(i,0,m1+1) bz[ar][i]=1;
        return; 
    }
    int len=rt-lt+1,i,i1,j=0,j1=0,p[101];
    p[1]=0;
    fo(i1,2,len)
    {
        i=i1+lt-1;
        j1=j+lt-1;
        while (j>0&&s1[j1+1]!=s1[i]) 
        {
            j=p[j];
            j1=j+lt-1;
        }
        if (s1[j1+1]==s1[i]) j++;
        j1=j+lt-1;
        p[i1]=j;
    }
    j=0;
    fo(i,1,m1)
    {
        j1=j+lt-1;
        while (j>0&&s1[j1+1]!=s2[i]) 
        {
            j=p[j];
            j1=j+lt-1;
        }
        if (s1[j1+1]==s2[i]) j++;
        j1=j+lt-1;
        if (j==len) bz[ar][i-j+1]=1;
    }
}
bool pd(int st)
{
    int i=st,j=1;
    if (bz[j][st]==0) return 0; 
    a[0]=0;
    while (i!=0&&i+a[j]-a[j-1]-2<=st+m-1) 
    {
        if (j==num-1&&bz[num][st+m-a[num]+a[num-1]+1]) return 1;
        i=next[j][i+a[j]-a[j-1]-2];
        j++;
    }
    return 0; 
}
int main()
{
    scanf("%s",s1+1);
    scanf("\n");
    scanf("%s",s2+1);
    n=strlen(s1+1);
    m=strlen(s2+1);
    num=0;
    int i,j;
    fo(i,1,m-1) s2[i+m]=s2[i]; 
    m1=2*m-1;
    fo(i,1,n) if (s1[i]=='*') a[++num]=i;
    a[++num]=n+1;
    memset(bz,0,sizeof(bz));
    fo(i,1,num)
    {
        kmp(i,a[i-1]+1,a[i]-1); 
    } 
    fod(i,m1-1,0)
    {
        fo(j,0,num-1)
        {
            next[j][i]=bz[j+1][i+1]?i+1:next[j][i+1];
        }
    }
    int ans=0;
    fo(i,1,m) 
    {
        if (i==2)
        {
            n++;
            n--;
        }
        if(pd(i)) ans++;
    }
    cout<<ans;
} 
1
0
查看评论

【NOIP2013模拟】归途与征程

Description给出两个字符串,A和B,|A|=n,|B|=m,并且A中有许多*——通配符。这个东西可以匹配任意的字符串,包括空串。现在问你,B的循环同构的字符串中,有多少个可以和A匹配? n<=100,m<=10^5Solution什么东东? 还以为是扩k呢。。。 实际上只...
  • alan_cty
  • alan_cty
  • 2016-05-30 19:46
  • 767

【NOIP2013模拟】归途与征程 题解+代码

DescriptionInput第一行为字符串A。 第二行为字符串B。Output输出在B的所有循环同构串中,有多少个能够与A匹配。Sample Input输入1: aaaa aaaa 输入2: a*a aaaaaa 输入3: * a*b*c * abacabadabacabaSa...
  • u011056504
  • u011056504
  • 2016-06-01 19:18
  • 340

[jzoj]3427. 【NOIP2013模拟】归途与征程(字符串DP+贪心)

Problem给定一个A串,一个B串,A串的’* ‘可以匹配B串的任意多个字符,若除’*’以外所有字符一一对应,则称A,B匹配,求在B串所有的循环串中有多少个与A匹配.Data constraint对于30%的数据,M<=20;对于80%的测试点,M<=200;对于100%的测试点,1&...
  • Algor_pro_king_John
  • Algor_pro_king_John
  • 2017-08-18 21:35
  • 175

JZOJ3427. 【NOIP2013模拟】归途与征程 (2017.8B组)

https://jzoj.net/senior/#main/show/3427 想法: 先把A串中所有连成一块的不含“”的子串提取出来,把b串copy一份,求f[i][j]表示b串第i位到i+len位是否和a串的第j个子串匹配(hash或暴力),然后在求一个next[i][j]表示i及后...
  • puppywolf
  • puppywolf
  • 2017-08-17 22:36
  • 87

归途与征程

题目描述简单的思路把B串倍长,那么新的串任意一个长度为M的子串都是B的循环同构串。 按照*号把A串分成了若干段,然后每一段都与B串做一次KMP匹配。 具体的,设一个bz[i,j]表示B串第i个位置为开头是否能与第j段匹配。 那么统计答案就是枚举循环同构串的头部,不断往后跑。 当然,如果A串的...
  • WerKeyTom_FTD
  • WerKeyTom_FTD
  • 2016-05-28 14:57
  • 343

归途与征程 Journey

题目描述:“感谢你们来访 Nescafe 之塔,封印的能量会在两天之内完全被贮存在神杯之中,你们也该回去了。” “不过圣主,我们还有一个问题。难道……Nescafe 就这样被封印成一座神杯,保存在塔中了吗?” “也许吧。谁知道呢?或许来年的秋天会有有识之士来开启它呢……” “有识之士?他是谁?...
  • zhangche0526
  • zhangche0526
  • 2017-02-07 19:56
  • 177

jzoj 3427 归途与征程

jzoj 3427
  • ssl_lyy
  • ssl_lyy
  • 2017-08-18 21:56
  • 116

[JZOJ 3427] 归途与征程

Description 对于100%的测试点,1<=N<=100,1<=M<=100000。Analysis我们可以把A串视为一些串中间隔着一些星号。 显然,A串头尾都没有星号是有星号的特殊情况。因为无星号可以跳过头尾的串变成头尾都是星号。 下图,上者A,下者B。 ...
  • lyd_7_29
  • lyd_7_29
  • 2016-06-01 12:41
  • 376

【JZOJ 3427】归途与征程

Solution 题意简化以后就是:在b串的同构中,有多少个可以按顺序匹配多个串。 我们可以先把a串拆开,每个做一遍KMP的预处理, 倍长b串,枚举b串的开头,依次匹配过去, 每次匹配的时候,记录一下上一次匹配失败的位置,直接从上次匹配失败的地方开始匹配;成功是也记录一下,判断一下
  • HOWARLI
  • HOWARLI
  • 2016-05-31 12:49
  • 632

【NOIP2013模拟】七夕祭

Sample Input4 32 5 4 32 1 33 2 44 2 4Sample Output-12Data ConstraintHint第一份订单满足后,4天剩余教室分数分别为0,3,2,3. 第二份订单要求第二天到第四天每天提供三个教室,而第三天剩余的教室数为二,因此无法满足。分配停止通知...
  • HownoneHe
  • HownoneHe
  • 2016-04-09 15:03
  • 683
    个人资料
    • 访问:74080次
    • 积分:3326
    • 等级:
    • 排名:第12079名
    • 原创:257篇
    • 转载:2篇
    • 译文:0篇
    • 评论:21条
    文章分类