关闭

[JZOJ 3427] 归途与征程

标签: dp模拟KMP
366人阅读 评论(0) 收藏 举报
分类:

Description

对于100%的测试点,1<=N<=100,1<=M<=100000。

Analysis

我们可以把A串视为一些串中间隔着一些星号。
显然,A串头尾都没有星号是有星号的特殊情况。因为无星号可以跳过头尾的串变成头尾都是星号。
下图,上者A,下者B。

我们可以对于A串中的小串与B串做一次KMP,搞一个bz[i][j]表示第i个小串是否能与B的第j个位置往后相应长度匹配。再搞一个f[i][j]表示第j个位置及其右边的第一个能与A串的i小串相匹配的位置。这样一直跳,跳,跳即可。时间复杂度是O(nm)的。

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,b,a) for(int i=b;i>=a;i--)
using namespace std;
const int N=110,M=200010;
int n,m,len,num,next[N],f[N][M],c[N];
char a[N],b[M],s[N];
bool p1,pn,bz[N][M];
void kmp(int st)
{
    int j=0;
    fo(i,2,n)
    {
        while(j && s[i]!=s[j+1]) j=next[j];
        next[i]=s[i]==s[j+1]?(++j):(j=0);
    }
    j=0;
    fo(i,2,m*2)
    {
        while(j && b[i]!=s[j+1]) j=next[j];
        if(b[i]==s[j+1]) j++;
        if(j==c[st]) bz[st][i-j+1]=1;
    }
    f[st][m*2+1]=m*2+1;
    fd(j,m*2,1)
        if(bz[st][j]) f[st][j]=j;
        else f[st][j]=f[st][j+1];
}
bool match(int x)
{
    int y=x+m-1,l=1,r=num;
    if(!p1)
    {
        if(!bz[l][x]) return 0;
        x+=c[l++];
    }
    if(!pn)
    {
        if(!bz[r][y-c[r]+1]) return 0;
        y-=c[r--];
    }
    for(;l<=r;l++)
    {
        x=f[l][x];
        if(x>y) return 0;
        x+=c[l]-1;
    }
    if(x>y) return 0;
    return 1;
}
int main()
{
    scanf("%s\n%s",a+1,b+1);
    n=strlen(a+1),m=strlen(b+1);
    p1=a[1]=='*',pn=a[n]=='*';
    fo(i,m+1,m*2) b[i]=b[i-m];
    int i=0;
    while(++i<=n)
    {
        int len=0;
        for(;i<=n && a[i]!='*';i++) s[++len]=a[i];
        if(!len) continue;
        c[++num]=len;
        kmp(num);
    }
    int ans=0;
    fo(i,1,m)
        if(match(i)) ans++;
    printf("%d",ans);
    return 0;
}
0
0
查看评论

【JZOJ 3427】归途与征程

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

jzoj 3427 归途与征程

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

归途与征程

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

归途与征程 Journey

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

【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
  • 762

[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
  • 167

【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
  • 325

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

DescriptionSolution注意,这里的匹配是全部都要匹配,不能落下一点。Code
  • hzj1054689699
  • hzj1054689699
  • 2016-06-01 12:47
  • 226

bzoj3059 归途与征程(字符串,优化dp)

各种奇怪的优化,然后各种恶心的细节,然后直接的暴力。
  • Icefox_zhx
  • Icefox_zhx
  • 2018-01-13 21:37
  • 67

[JZOJ4918]最近公共祖先

题目大意给定一棵nn个节点的有根树,节点编号11到nn,根节点为11号点。每个节点要么是黑色要么是白色,并且有权值wiw_i,初始时所有节点都是白色的。现在总共有mm个操作,分以下两种: ∙\bullet将节点vv的颜色修改为黑色黑色 ∙\bullet给定vv,要求找到一个黑色节点uu,最大化啊...
  • a_crazy_czy
  • a_crazy_czy
  • 2016-12-10 20:50
  • 902
    个人资料
    • 访问:114878次
    • 积分:4756
    • 等级:
    • 排名:第7206名
    • 原创:341篇
    • 转载:8篇
    • 译文:0篇
    • 评论:35条
    公告
    bzoj3110 jzoj 5295 5260 5261 5316
    最新评论
    文章分类