单词缩写(abbr.cpp)每日一题
题目描述:
YXY 发现好多计算机中的单词都是缩写,如 GDB,它是全称 Gnu DeBug 的缩写。但是,有时缩写对应的全称并不固定,如缩写 LINUX,可以理解为:
(1)LINus's UniX (2)LINUs's miniX (3)Linux Is Not UniX
现在 YXY 给出一个单词缩写,以及一个固定的全称(由若干个单词组成,用空格分隔)。全称中可能会有无效的单词,需要忽略掉,一个合法缩写要求每个有效的单词中至少有一个
字符出现在缩写中,缩写必须按顺序出现在全称中。对于给定的缩写和一个固定的全称,问有多少种解释方法。解释方法为缩写的每个字母出现在全称中每个有效单词中的位置,有一个字母位置不同,就认为是不同的解释方法。
输入格式:
第一行输入一个 N,表示有 N 个无效单词;接下来 N 行分别描述一个由小写字母组成的无效单词;接下来是若干个询问,先给出缩写(只有大写字母),然后给出一个全称。读
入以“LAST CASE”结束。
输出格式:
对于每个询问先输出缩写,如果当前缩写不合法。则输出“is not a valid abbreviation”,否则输出“can be formed in i ways”(i 表示解释方法种数)。
样例输入 :
2
and
of
ACM academy of computer makers
RADAR radio detection and ranging
LAST CASE
样例输出:
ACM can be formed in 2 ways
RADAR is not a valid abbreviation
数据范围 : 1<=N<=100,每行字符串长度不超过 150,询问不超过 20,所给数据计算出
来的最后方案数不超过 10^9。
数据范围很小,此题暴力修改+一般DP
贴代码:
1 #include<iostream> 2 #include<algorithm> 3 #include<cmath> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 typedef long long LL; 8 inline int read() 9 { 10 int x=0,f=1;char c=getchar(); 11 while(!isdigit(c)){if(c=='-')f=-1;c=getchar();} 12 while(isdigit(c)){x=x*10+c-'0';c=getchar();} 13 return x*f; 14 } 15 int n,l1,l2,l3; 16 char s[160],sc[110][160],mb[160],t[160]; 17 bool judge(char *a,char *b) 18 { 19 int x=strlen(a),y=strlen(b); 20 if(x!=y)return 1; 21 for(int i=0;i<x;i++) 22 if(a[i]!=b[i])return 1; 23 return 0; 24 } 25 int main() 26 { 27 freopen("abbr.in","r",stdin); 28 freopen("abbr.out","w",stdout); 29 n=read(); 30 for(int i=0;i<n;i++)scanf("%s",sc[i]); 31 cin.getline(s,160); 32 while(1) 33 { 34 char tmp[160]; 35 memset(tmp,0,sizeof(tmp)); 36 memset(mb,0,sizeof(mb)); 37 memset(s,0,sizeof(s)); 38 cin.getline(tmp,151); 39 if(!strcmp(tmp,"LAST CASE"))break; 40 int l0=strlen(tmp);;bool ok=0; 41 l1=l2=l3=0; 42 int i = 0; 43 while(tmp[i] != ' ') mb[l1++] = tmp[i++]; 44 for(i++; i < l0; i++) s[l2++] = tmp[i]; 45 // printf("%s\n%s\n", mb, s); 46 ok=1; 47 int st=0,en=0,now=0; 48 bool had[151]; 49 memset(had,0,sizeof(had)); 50 memset(tmp,0,sizeof(tmp)); 51 memset(t, 0, sizeof(t)); 52 for(i = 0; i < l2;) { 53 char tw[160]; int tcnt = 0; 54 while(i < l2 && s[i] != ' ') { 55 tw[tcnt++] = s[i]; 56 i++; 57 } 58 i++; 59 tw[tcnt] = 0; 60 bool ok = 1; 61 for(int j = 0; j < n; j++) if(!strcmp(sc[j], tw)) { 62 ok = 0; break; 63 } 64 if(!ok) continue; 65 for(int j = 0; j < tcnt; j++) t[l3++] = tw[j]; 66 t[l3++] = ' '; 67 } 68 l3--; 69 // printf("%s %s\n", mb, t); 70 int cnt=1; 71 for(int i=0;i<l3;i++) if(t[i]==' ')cnt++; 72 if(cnt>l1) 73 { 74 printf("%s is not a valid abbreviation\n",mb); 75 continue; 76 } 77 int dp[160][160][2]; 78 memset(dp,0,sizeof(dp)); 79 for(int i=l1;i>=1;i--)mb[i]=mb[i-1]; 80 for(int i=l3;i>=1;i--)t[i]=t[i-1]; 81 // printf("new: %s %s\n", mb + 1, t + 1); 82 dp[0][0][0]=1; 83 for(int i=0;i<=l3;i++) 84 { 85 if(t[i]==' ')continue; 86 for(int j=0;j<=min(i,l1);j++) 87 { 88 // printf("%d %d: %d %d\n", i, j, dp[i][j][0], dp[i][j][1]); 89 if(t[i+1]==' ') 90 { 91 if(t[i+2]-'a'==mb[j+1]-'A')dp[i+2][j+1][1]+=dp[i][j][1]; 92 dp[i+2][j][0]+=dp[i][j][1]; 93 continue; 94 } 95 if(t[i+1]-'a'==mb[j+1]-'A')dp[i+1][j+1][1]+=(dp[i][j][0]+dp[i][j][1]); 96 dp[i+1][j][0]+=dp[i][j][0];dp[i+1][j][1]+=dp[i][j][1]; 97 } 98 } 99 for(int i=1;i<=l1;i++)printf("%c",mb[i]); 100 if(!dp[l3][l1][1])printf(" is not a valid abbreviation\n"); 101 else printf(" can be formed in %d ways\n",dp[l3][l1][1]); 102 103 } 104 return 0; 105 }