zoukankan      html  css  js  c++  java
  • 無名(noname)

    【问题描述】

    因为是蒯的题所以没想好名字,为什么要用繁体呢?去看《唐诗三百首》吧!

    题意很简单,给你一个串,求他有多少个不同的子串,满足前缀为A,后缀为B。

    需要注意的是,串中所有的字母都是小写字母。

    友情提示:如果你过不了样例,请注意是不同的子串。                    

    【输入文件】

    一共3行。

    第一行母串S;

    第二行串A;

    第三行串B。

    【输出文件】

        一个数,即有多少不同的子串。

    【输入样例】

    abababab

    a

    b

    【输出样例】

    4

    【数据规模和约定】

    100%:

    length(S)<=2000;

    length(A)<=2000;

    length(B)<=2000;

    30%:都少个0

    字符串hash

    首先,枚举每一个后缀是否前缀为A,front[i]表示i~l-1的前缀是否为A

    同理处理出bside[i]表示0~i的后缀是否为B

    枚举左右端点,可知当2个数组都为1才为一个解

    但是解不能重复

    于是用字符串hash,就是将字符串转数

    hash[i]表示0~i的hash值

    hash[i]=((hash[i-1]*p+idx(s[i]))%Mod

    Mod和p都要慎重考虑,p取31,Mod取1e7+7

    那么l~r的hash值为:hash(l~r)=(hash[r]-hash[l-1]*p^(r-l+1)+Mod)%Mod

    一般Mod取1e9+7,但是这里要用bool数组,所以取1e7+7

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 int p=31,Mod=100000007;
     7 int l,la,lb,front[2001],bside[2001];
     8 char s[2001],A[2001],B[2001];
     9 long long pow[2001],hash[2001],ans;
    10 bool vis[100000007];
    11 bool ask(int x,int y)
    12 {
    13     long long h=(hash[y]-(hash[x-1]*pow[y-x+1]%Mod)+Mod)%Mod;
    14     if (vis[h]==0)
    15     {
    16      vis[h]=1;
    17      return 1;
    18     }
    19     else 
    20     {
    21      return 0;
    22     }
    23 }
    24 int main()
    25 {int i,j;
    26 //freopen("noname.in","r",stdin);
    27 //freopen("noname.out","w",stdout);
    28     cin>>s;
    29     cin>>A;
    30     cin>>B;
    31     l=strlen(s);
    32     la=strlen(A);
    33     lb=strlen(B);
    34      for (i=0;i<l;i++)
    35      {
    36         for (j=1;j<=la,j+i-1<l;j++)
    37          if (A[j-1]!=s[i+j-1]) break;
    38         if (j>la)
    39          front[i]=1;
    40      }
    41      for (i=l-1;i>=0;i--)
    42      {
    43         for (j=1;j<=lb,i-j+1>=0;j++)
    44         if (B[lb-j]!=s[i-j+1]) break;
    45         if (j>lb)
    46          bside[i]=1;
    47      }
    48      hash[1]=(int)s[0]-96;
    49     for (i=2;i<=l;i++)
    50     {
    51       hash[i]=(hash[i-1]*p+(int)s[i-1]-96)%Mod;
    52     }
    53     pow[0]=1;
    54      for (i=1;i<=l;i++)
    55       pow[i]=(pow[i-1]*p)%Mod;
    56     for (i=0;i<l;i++)
    57     {
    58      for (j=i+max(la,lb)-1;j<l;j++)
    59      if (front[i]&&bside[j])
    60        if (ask(i+1,j+1)) ans++;
    61     }
    62 cout<<ans;
    63 }
  • 相关阅读:
    luogu 1726 上白泽惠音
    POJ1419 Graph Coloring(最大独立集)(最大团)
    POJ2284 That Nice Euler Circuit (欧拉公式)(计算几何 线段相交问题)
    POJ 1966 Cable TV Network(顶点连通度的求解)
    POJ 1523 SPF(寻找关节点)
    Dwarves (有向图判环)
    POJ 3041 Asteroids(最小点覆盖集)
    POJ 1043 What's In A Name?(唯一的最大匹配方法)
    POJ Girls and Boys (最大独立点集)
    Jewelry Exhibition(最小点覆盖集)
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7418930.html
Copyright © 2011-2022 走看看