单词缩写(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
%s
", 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
", 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
",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
", 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
", 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
");
101         else  printf(" can be formed in %d ways
",dp[l3][l1][1]);
102         
103     }
104     return 0;
105 }
原文地址:https://www.cnblogs.com/FYH-SSGSS/p/6049062.html