码迷,mamicode.com
首页 > 其他好文 > 详细

P1624 单词缩写

时间:2017-10-26 15:38:46      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:答案   inux   enter   badge   长度   cut   +=   cti   理解   

P1624 单词缩写

题目描述

树树发现好多计算机中的单词都是缩写,如GDB是全称Gnu DeBug的缩写。但是,有时候缩写对应的全称会不固定,如缩写LINUX可以理解为:

(1) LINus’s UniX

(2) LINUs’s miniX

(3) Linux Is Not UniX

现在树树给出一个单词缩写,以及一个固定的全称(若干个单词组成,空格隔开)。全

称中可能会有无效的单词,需要忽略掉,一个合法缩写要求每个有效单词中至少有一个字符出现在缩写中,所写必须按顺序出现在全称中。

对于给定的缩写和一个固定的全称,问有多少种解释方法?解释方法为所写的每个字母在全称每个有效单词中出现的位置,有一个字母位置不同,就认为是不同的解释方法。

输入输出格式

输入格式:

 

第一行输入一个N,表示有N个无效单词;

接下来N行分别描述一个由小写字母组成的无效单词;

最后是若干个询问,先给出缩写(只有大写字母),然后给出一个全称,读入以“LAST CASE”结束。

[数据规模]

1≤N≤100,每行字符串长度不超过150,询问次数不超过20,最后方案数不超过10^9。

 

输出格式:

 

对于每个询问先输出缩写,如果当前缩写不合法,则输出“is not a valid abbreviation”,否则输出“can be formaed in i ways”(i表示解释方法数)

 

输入输出样例

输入样例#1: 复制
2
and
of
ACM academy of computer makers
RADAR radio detection and ranging
LAST CASE
输出样例#1: 复制
ACM can be formed in 2 ways
RADAR is not a valid abbreviation

 

洛谷题解

看大家都是N^4或N3算法,N2算法还没有,赶紧水一发

基本思路:

把所有串连接起来,记录每个串的尾后位置,

设f[k][i]表示现在在处理缩写的第K个字符,在大字符串中第I个位置对前面字符的总贡献数,则f[k][i]=Σf[k-1][j],

其中j表示满足条件的前一个缩写字符。其中满足条件的定义为“无空缺单词,且是前一个字母”。则答案为Σf[最后一个字符][j],(1<=j<=n)。

为避免出现同一字母出现位置的不同,用一个数组进行标记即可。

标记要一次打完才能更新!!!

 

  1 #include<bits/stdc++.h>
  2 #define RG register
  3 using namespace std;
  4 
  5 int n;
  6 char a[110][200];//无效单词
  7 char c1[200];
  8 char c[200];
  9 char all[200][200];//有效单词
 10 int ma[26][200];//每个字母的有效位置
 11 int tag[200];
 12 int tag1[200];//两个标记
 13 int cut[200];//单词的尾后位置
 14 int sum[26];//出现的次数
 15 int f[200][200];//dp数组
 16 
 17 int main()
 18 {
 19     scanf("%d\n",&n);
 20     for(RG int i=1;i<=n;i++)
 21     {
 22         scanf("%s",a[i]);
 23     }
 24     scanf("%s",c1);
 25     while(1)
 26     {
 27         RG int i_1_1=1;
 28         strcpy(c,c1);
 29         if(strcmp(c,"LAST")==0)
 30         {
 31             scanf("%s",all[i_1_1++]);
 32             if(strcmp(all[i_1_1-1],"CASE")==0) break;
 33         }
 34         while(cin>>all[i_1_1++])
 35         {
 36             RG int j=0;
 37             int len=strlen(all[i_1_1-1]);
 38             while(all[i_1_1-1][j]<a&&j<len) j++;
 39             if(j>=len)
 40             {
 41                 strcpy(c1,all[i_1_1-1]);
 42                 i_1_1--;
 43                 break;
 44             }
 45             else
 46             {
 47                 for(RG int i=1;i<=n;i++)
 48                 {
 49                     if(strcmp(a[i],all[i_1_1-1])==0)
 50                     {
 51                         i_1_1--;
 52                         break;
 53                     }
 54                 }
 55             }
 56         }
 57         i_1_1--;
 58         printf("%s ",c);
 59         int len=strlen(c);
 60         for(RG int i=0;i<len;i++)
 61         {
 62             c[i]=c[i]+32;
 63         }
 64         //读入
 65         if(len<i_1_1)//分类讨论
 66         {
 67             puts("is not a valid abbreviation");
 68         }
 69         else if(len==i_1_1)
 70         {
 71             int ans=1;
 72             for(RG int i=0;i<len;i++)
 73             {
 74                 int len2=strlen(all[i+1]);
 75                 RG int tmp=0;
 76                 for(RG int j=0;j<len2;j++)
 77                 {
 78                     if(all[i+1][j]==c[i]) tmp++;
 79                 }
 80                 if(tmp) ans*=tmp;
 81                 else
 82                 {
 83                     puts("is not a valid abbreviation");
 84                     break;
 85                 }
 86             }
 87             printf("can be formed in %d ways\n",ans);
 88         }
 89         else //重点
 90         {
 91             memset(sum,0,sizeof(sum));
 92             memset(f,0,sizeof(f));
 93             memset(tag,0,sizeof(tag));
 94             memset(cut,0,sizeof(cut));
 95             memset(ma,0,sizeof(ma));
 96             int cz=strlen(all[1]);
 97             for(int i=2;i<=i_1_1;i++)
 98             {
 99                  strcpy(all[1]+cz,all[i]);
100                  cut[i-1]=cz;
101                  cz=strlen(all[1]);
102             }
103             //连串
104             cut[i_1_1]=cz;
105             for(int i=0;i<cz;i++)
106             {
107                 int j=all[1][i]-a;
108                 ma[j][++sum[j]]=i;
109             }
110             //记字母位置
111             for(int k=0;k<len;k++)
112             {
113                 int id=c[k]-a;
114                 int ci=min(k+1,i_1_1);
115                 int ti=1;
116                 for(int i=0;i<cz;i++)
117                 {
118                     tag1[i]=tag[i];
119                 }//备份
120                 for(int i=1;i<=sum[id]&&ma[id][i]<cut[ci];i++)
121                 {
122                     while(ma[id][i]>=cut[ti]) ti++;
123                     if(i_1_1-ti>len-k-1) continue;
124                     if(k==0)
125                     {
126                         tag1[ma[id][i]]=0;//标记
127                         f[k][i]=1;//初始值
128                     }
129                     else
130                     {
131                         int t=c[k-1]-a;
132                         for(int j=1;j<=sum[t];j++)
133                         {
134                             if(ma[t][j]<ma[id][i]&&ma[t][j]>=cut[ti-2]&&tag[ma[t][j]]==k-1)
135                             {
136                                 f[k][i]+=f[k-1][j];//转移
137                                 tag1[ma[id][i]]=k;//标记×2
138                             }
139                         }
140                     }
141                 }
142                 for(int i=0;i<cz;i++)
143                 {
144                     tag[i]=tag1[i];//备份
145                 }
146             }
147             int ans=0;
148             for(int i=1;i<=sum[c[len-1]-a];i++)
149             {
150                 ans+=f[len-1][i];//求和
151             }
152             if(ans)
153             {
154                 printf("can be formed in %d ways\n",ans);
155             }
156             else puts("is not a valid abbreviation");
157         }
158     }
159     return 0;
160 }

 

P1624 单词缩写

标签:答案   inux   enter   badge   长度   cut   +=   cti   理解   

原文地址:http://www.cnblogs.com/Renyi-Fan/p/7736540.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!