• cf727e


    题意:给你一个模式串和一堆长度相同的不相同的匹配串,问是否有一个方案可以让这个模式串由这些匹配串首尾相连组成,每个串只能出现一次.

    思路:还是比较简单的,显然模式串每个位置最多匹配一个匹配串,因为所有的匹配串严格不同,每个位置有没有匹配哪个匹配串用ac自动机很容易就能跑出来,然后枚举一下位置就ok,还有模式串应该在开头加上尾部的一些字符,因为要求的是这个模式串要看成一个环.

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 char aim[2000010];
      4 int pos[2000010];
      5 char temp[100010];
      6 int total;
      7 struct Root
      8 {
      9     Root *next[26];
     10     int count;
     11     Root *fail;
     12     Root()
     13     {
     14         for(int i=0; i<26; i++)
     15             next[i]=NULL;
     16         fail=NULL;
     17         count=0;
     18     }
     19 };
     20 queue<Root *>q;
     21 class AC_auto
     22 {
     23 public:
     24     AC_auto();
     25     void insert(char object[],int num);
     26     void ac_auto();
     27     void match(char aim[]);
     28 private:
     29     Root *root;
     30 };
     31 AC_auto::AC_auto()
     32 {
     33     root=new Root();
     34 }
     35 void AC_auto::insert(char object[],int num)
     36 {
     37     int len=strlen(object);
     38     Root *temp=root;
     39     for(int i=0; i<len; i++)
     40     {
     41         if(temp->next[object[i]-'a']==NULL)
     42         {
     43             Root *temp1=new Root();
     44             temp->next[object[i]-'a']=temp1;
     45         }
     46         temp=temp->next[object[i]-'a'];
     47     }
     48     temp->count=num;
     49 }
     50 void AC_auto::ac_auto()
     51 {
     52     while(!q.empty())q.pop();
     53     q.push(root);
     54     Root *temp1,*temp2;
     55     while(!q.empty())
     56     {
     57         temp1=q.front();
     58         q.pop();
     59         for(int i=0; i<26; i++)
     60         {
     61             if(temp1->next[i])
     62             {
     63                 if(temp1==root)
     64                     temp1->next[i]->fail=root;
     65                 else
     66                 {
     67                     temp2=temp1->fail;
     68                     while(temp2)
     69                     {
     70                         if(temp2->next[i])
     71                         {
     72                             temp1->next[i]->fail=temp2->next[i];
     73                             break;
     74                         }
     75                         temp2=temp2->fail;
     76                     }
     77                     if(temp2==NULL)
     78                         temp1->next[i]->fail=root;
     79                 }
     80                 q.push(temp1->next[i]);
     81             }
     82         }
     83     }
     84 }
     85 void AC_auto::match(char aims[])
     86 {
     87     int len=strlen(aims);
     88     Root *temp1,*temp=root;
     89     for(int i=0; i<len; i++)
     90     {
     91         if(aims[i]>'z'||aims[i]<'a')
     92         {
     93             temp=root;
     94             continue;
     95         }
     96         while(temp->next[aims[i]-'a']==NULL&&temp!=root)
     97             temp=temp->fail;
     98         temp=temp->next[aims[i]-'a'];
     99         if(!temp)temp=root;
    100         if(temp->count)
    101             pos[i]=temp->count;
    102     }
    103 }
    104 bool sign[100010];
    105 int main()
    106 {
    107     int n,k;
    108     scanf("%d%d",&n,&k);
    109     scanf("%s",aim+k);
    110     for(int i=0;i<k;i++)
    111         aim[i]=aim[(n+1)*k-k+i];
    112     AC_auto *ac_auto=new AC_auto();
    113     int g;
    114     scanf("%d",&g);
    115     for(int i=1;i<=g;i++)
    116     {
    117         scanf("%s",temp);
    118         ac_auto->insert(temp,i);
    119     }
    120     ac_auto->ac_auto();
    121     ac_auto->match(aim);
    122     for(int i=k;i<2*k;i++)
    123     {
    124         for(int j=i;j<n*k+k;j+=k)
    125         {
    126             if(pos[j]==0)
    127                 break;
    128             else if(sign[pos[j]])
    129                 break;
    130             sign[pos[j]]=true;
    131             if(j+k>=n*k+k)
    132             {
    133                 printf("YES
    ");
    134                 for(int j=i;j<n*k+k;j+=k)
    135                     printf("%d ",pos[j]);
    136                 return 0;
    137             }
    138         }
    139         for(int j=i;j<n*k+k;j+=k)
    140         {
    141             if(pos[j]==0)
    142                 break;
    143             sign[pos[j]]=false;
    144         }
    145     }
    146     printf("NO
    ");
    147     return 0;
    148 }
  • 相关阅读:
    window计时器函数
    日期函数
    字符的方法
    五大主流浏览器与四大内核
    向一个排好序的数组中插入一个数组。
    冒泡与排序
    数组去重方法1,2,3
    有执行语句:console.log(fn2(2)[3]),补充函数,使执行结果为"hello"
    面试题:一个函数的调用 fn(2)(3)(4) 得到的结果位24; 这个函数是柯里化函数运用了闭包原理
    python中append()与extend()方法的区别
  • 原文地址:https://www.cnblogs.com/lthb/p/6045074.html
Copyright © 2020-2023  润新知