P1624 單詞縮寫

2021-09-07 15:28:37 字數 4046 閱讀 6664

樹樹發現好多計算機中的單詞都是縮寫,如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

andof

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

洛谷題解

先暴力去掉所有的單詞,只對有效單詞進行計算。

dp[i][j]表示前i個單詞使用了前j個大寫字母的方案數

初始條件dp[0][0]=1

轉移:若第i個單詞使用第j到第j+k個大寫字母的方案數為temp[k]

則dp[i][j+k]=dp[i-1][j-1]*temp[k]

最終ans=dp[n][m]

時間複雜度o(l1*n*l2*l2)

空間複雜度o(l1*n*l2)

l1縮寫長度 n全稱中單詞的個數 l2全稱中乙個單詞的長度

這屬於兩個串匹配的問題,就乙個前i,乙個前j就好,反正是找子問題。

1 #include2 #include3 #include4 #include5

using

namespace

std;

6char w[101][150];7

char s[150],let[150];8

char over[9]=;

9struct

word

10a[150

];14

intt,n,m,len;

15int dp[100][150],temp[150

];16

bool

case_is_over()

1722

intmain()

2343 p++;

44while (p4552

for (int i=1;i<=t;i++)

53if (strcmp(w[i],a[n].c)==0)54

59 p++;60}

61 memset(dp,0,sizeof

(dp));

62 dp[0][0]=1;63

for (int i=1;i<=n;i++) //

列舉單詞

64for (int j=i;j<=i+m-n;j++) //

列舉當前單詞使用大寫字母的起始位置

6575

if (dp[n][m]) printf("

can be formed in %d ways\n

",dp[n][m]);

76else printf("

is not a valid abbreviation\n");

77}78return0;

79 }

看大家都是n^4或n³演算法,n²演算法還沒有,趕緊水一發

基本思路:

把所有串連線起來,記錄每個串的尾後位置,

設f[k][i]表示現在在處理縮寫的第k個字元,在大字串中第i個位置對前面字元的總貢獻數,則f[k][i]=σf[k-1][j],

其中j表示滿足條件的前乙個縮寫字元。其中滿足條件的定義為「無空缺單詞,且是前乙個字母」。則答案為σf[最後乙個字元][j],(1<=j<=n)。

為避免出現同一字母出現位置的不同,用乙個陣列進行標記即可。

1 #include2

#define rg register

3using

namespace

std;45

intn;

6char a[110][200];//

無效單詞

7char c1[200];8

char c[200];9

char all[200][200];//

有效單詞

10int ma[26][200];//

每個字母的有效位置

11int tag[200

];12

int tag1[200];//

兩個標記

13int cut[200];//

單詞的尾後位置

14int sum[26];//

出現的次數

15int f[200][200];//

dp陣列

1617

intmain()

1824 scanf("%s"

,c1);

25while(1)26

34while(cin>>all[i_1_1++])

3545

else

4654}55

}56}57 i_1_1--;

58 printf("

%s "

,c);

59int len=strlen(c);

60for(rg int i=0;i)

6164

//讀入

65if(len//

分類討論

6669

else

if(len==i_1_1)

7080

if(tmp) ans*=tmp;

81else

8286

}87 printf("

can be formed in %d ways\n

",ans);88}

89else

//重點

90103

//連串

104 cut[i_1_1]=cz;

105for(int i=0;i)

106110

//記字母位置

111for(int k=0;k)

112//

備份120

for(int i=1;i<=sum[id]&&ma[id][i])

121129

else

130139

}140

}141

}142

for(int i=0;i)

143146

}147

int ans=0

;148

for(int i=1;i<=sum[c[len-1]-'

a'];i++)

149152

if(ans)

153156

else puts("

is not a valid abbreviation");

157}

158}

159return0;

160 }

FZU 1687 單詞縮寫

單詞縮寫 time limit 1s memory limit 32m accepted submit 228 total submit 622 國際會議的檔案,中文的印刷本總是最薄的一冊。所以,小明決定縮寫一段段的英文。他的縮寫規則十分的簡單 在一段只由a z,a z和空格組成的英文段落中,以空格...

英文單詞縮寫查詢

公尺老師要我們發現英文縮寫就去查,但是我發現自己裝的金山詞霸只能查縮寫是什麼意思,極少能查出全寫。所以自己動手做了乙個查詢英文縮寫的小工具。經過3天的測試和改進這個小工具基本上沒有bug了,而且在一些小的細節上做了非常貼心的處理。究竟有多貼心,自己去體會吧。還有就是這個小工具沒有單詞庫,沒有縮寫單詞...

英文單詞縮寫查詢

公尺老師要我們發現英文縮寫就去查,但是我發現自己裝的金山詞霸只能查縮寫是什麼意思,極少能查出全寫。所以自己動手做了乙個查詢英文縮寫的小工具。經過3天的測試和改進這個小工具基本上沒有bug了,而且在一些小的細節上做了非常貼心的處理。究竟有多貼心,自己去體會吧。還有就是這個小工具沒有單詞庫,沒有縮寫單詞...