樹樹發現好多計算機中的單詞都是縮寫,如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:
複製
2andof
acm academy of computer makers
radar radio detection and ranging
last case
輸出樣例#1:
複製
acm can be formed in 2 waysradar 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 #include5using
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了,而且在一些小的細節上做了非常貼心的處理。究竟有多貼心,自己去體會吧。還有就是這個小工具沒有單詞庫,沒有縮寫單詞...