zoukankan      html  css  js  c++  java
  • UVALive

    input

    字符串s   1<=len(s)<=300000

    n    1<=n<=4000

    word1

    word2

    ...

    wordn

    1<=len(wordi)<=100

    output

    由一个或多个word拼成s的种数%20071027.

    做法1:dp:单词长度最多为100,d[i]表示到第i个字符结束的种数,则如果d[j]到d[i]这段字符能从trie中找到,d[i]+=d[j],i-100<j<=i

      1 //1225ms
      2 #include <cstdio>
      3 #include <queue>
      4 #include <cstring>
      5 #include <iostream>
      6 #include <cstdlib>
      7 #include <algorithm>
      8 #include <vector>
      9 #include <map>
     10 #include <set>
     11 #include <ctime>
     12 #include <cmath>
     13 #include <cctype>
     14 #define MAX 100000
     15 #define LL long long
     16 #define mod 20071027
     17 struct trie
     18 {
     19     int ch[4*MAX][26];
     20     bool val[4*MAX];
     21     int sz;
     22     trie()
     23     {
     24         sz=1;
     25         memset(ch[0],0,sizeof(ch[0]));
     26     }
     27     int idx(char &c) { return c-'a';}
     28     char* insert(char*s)
     29     {
     30         int u=0;
     31         for(;*s;s++)
     32         {
     33             int c=idx(*s);
     34             if(!ch[u][c])
     35             {
     36                 memset(ch[sz],0,sizeof(ch[sz]));
     37                 val[sz]=0;
     38                 ch[u][c]=sz++;
     39             }
     40             u=ch[u][c];
     41         }
     42         val[u]=1;
     43         return s;
     44     }
     45     int find(char*s,int n)
     46     {
     47         int u=0;
     48         for(int i=0;i<n;i++)
     49         {
     50             int c=idx(s[i]);
     51             if(!ch[u][c]) return 0;
     52             u=ch[u][c];
     53         }
     54         return val[u];
     55     }
     56 };
     57 trie t;
     58 char s[3*MAX+10],word[110];
     59 int n,maxl,d[3*MAX+10],cas=1;
     60 int main()
     61 {
     62     //freopen("/home/user/桌面/in","r",stdin);
     63     while(scanf("%s",s)==1)
     64     {
     65         memset(t.ch[0],0,sizeof(t.ch[0]));
     66         t.sz=1;
     67         scanf("%d",&n);
     68         maxl=0;
     69         while(n--)
     70         {
     71             scanf("%s",word);
     72             int l=t.insert(word)-word;
     73             maxl=std::max(maxl,l);
     74         }
     75         n=strlen(s);
     76         memset(d,0,sizeof(d));
     77         int u=0,work=0;
     78         for(int i=0;i<maxl;i++)
     79         {
     80             int c=t.idx(s[i]);
     81             if(!t.ch[u][c]) break;
     82             u=t.ch[u][c];
     83             if(t.val[u])
     84             {
     85                 work=1;
     86                 d[i]=1;
     87             }
     88         }
     89 //        for(int i=0;i<=n;i++) printf("%d ",d[i]);printf("
    ");
     90         if(work)
     91         {
     92                for(int i=1;i<n;i++)
     93             {
     94                 for(int j=1;j<=maxl;j++)
     95                 {
     96                     if(i-j>=0&&t.find(s+i-j+1,j)) d[i]=(d[i]+d[i-j])%mod;
     97                 }
     98             }
     99         }
    100 //        for(int i=0;i<=n;i++) printf("%d ",d[i]);printf("
    ");
    101         printf("Case %d: %d
    ",cas++,d[n-1]);
    102     }
    103     //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
    104     return 0;
    105 }
    dp

    做法2:直接模拟:一开始只有一条路找,每个单词结束时分出一条路从头开始

     1 //79ms
     2 #include <cstdio>
     3 #include <queue>
     4 #include <cstring>
     5 #include <iostream>
     6 #include <cstdlib>
     7 #include <algorithm>
     8 #include <vector>
     9 #include <map>
    10 #include <set>
    11 #include <ctime>
    12 #include <cmath>
    13 #include <cctype>
    14 #define MAX 100000
    15 #define LL long long
    16 #define mod 20071027
    17 struct trie
    18 {
    19     int ch[4*MAX][26];
    20     bool val[4*MAX];
    21     int sz;
    22     trie()
    23     {
    24         sz=1;
    25         memset(ch[0],0,sizeof(ch[0]));
    26     }
    27     int idx(char &c) { return c-'a';}
    28     void insert(char*s)
    29     {
    30         int u=0;
    31         for(;*s;s++)
    32         {
    33             int c=idx(*s);
    34             if(!ch[u][c])
    35             {
    36                 memset(ch[sz],0,sizeof(ch[sz]));
    37                 val[sz]=0;
    38                 ch[u][c]=sz++;
    39             }
    40             u=ch[u][c];
    41         }
    42         val[u]=1;
    43     }
    44 };
    45 trie t;
    46 char s[3*MAX+10],word[110];
    47 int n,cas=1,head[2][110],count[2][110],num[2];
    48 int main()
    49 {
    50     //freopen("/home/user/桌面/in","r",stdin);
    51     while(scanf("%s",s)==1)
    52     {
    53         memset(t.ch[0],0,sizeof(t.ch[0]));
    54         t.sz=1;
    55         scanf("%d",&n);
    56         while(n--)
    57         {
    58             scanf("%s",word);
    59             t.insert(word);
    60         }
    61         int d=1;
    62         num[d]=1;
    63         head[d][0]=0;
    64         count[d][0]=1;
    65         for(char*p=s;*p;p++,d^=1)
    66         {
    67 //            printf("%d %d
    ",count[d][0],d);
    68             int &idx=num[d^1]=1;
    69             int c=t.idx(*p);
    70             head[d^1][0]=0;
    71             count[d^1][0]=0;
    72             for(int i=0;i<num[d];i++)
    73             {
    74                 int &f=head[d][i];
    75                 if(t.ch[f][c])//继续走到下一个字母
    76                 {
    77                     if(t.val[t.ch[f][c]])//走完一个单词,从头开始,总是head[d][0]
    78                     {
    79                         count[d^1][0]+=count[d][i];
    80                         count[d^1][0]%=mod;
    81                     }
    82                     head[d^1][idx]=t.ch[f][c];
    83                     count[d^1][idx++]=count[d][i];
    84                 }
    85             }
    86         }
    87 //        printf("%d %d
    ",count[d][0],d);
    88         printf("Case %d: %d
    ",cas++,count[d][0]);
    89     }
    90     //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
    91     return 0;
    92 }
    模拟
  • 相关阅读:
    按钮UIButton内图片和文字位置的设置(两种方式)
    关于Xcode上的Other linker flags基本介绍
    GCD定时器
    线程间的通信(3种方式)
    scrollView中内部控件的悬停
    十七:字符串文件的读写
    十六:NSString的创建以及相关细节
    十五:NSValue
    react生命周期遇到的问题
    笔记----深入浅出《React和Redux》第四章
  • 原文地址:https://www.cnblogs.com/cdyboke/p/5016006.html
Copyright © 2011-2022 走看看