你的儿子小明打字水平有限,当他希望打出某个单词如 smart 时,他会错误地按到键盘上其他字母,例如形成 asnmaaaert 这样的尴尬情况。更加令人崩溃的是,小明还不会用"退回"键或者删除功能来清理错误字母。现在小明从一个词汇表里挑了若干个单词进行打字,词汇表里的所有n个单词都已知。请你识别出小明至少打错了几个字符? 换句话说,也就是去掉至少几个字符,可以使剩下的内容由词汇表里的真单词拼写出来? 输入输出格式 输入格式 输入文件typist2.in 先输入一行为正整数n和L,代表真的单词数,以及小明打了L个字符。n<=1000 第二行字符串,代表小明的打字内容,都由小写字母组成。长度不超过1000 之后共n行,每行一个英文单词,都由小写字母组成。长度均不超过1000。 输出格式 输出文件typist2.out 输出共一行,为一个整数。 输入输出样例 输入样例#1: 3 12 helllowordld hello world word 输出样例#1: 2 输入样例#2: 无 输出样例#2: 无 输入样例#3: 无 输出样例#3: 无
时间: 2024-04-12 09:29:22 浏览: 200
这个问题可以使用动态规划来解决。我们可以创建一个大小为L+1的数组dp,其中dp[i]表示在输入字符串的前i个字符中,最少需要删除多少个字符才能拼写出词汇表中的真单词。初始时,将dp数组所有元素初始化为无穷大(表示不可达)。
然后,我们遍历输入字符串的每个字符,对于每个字符,我们再遍历词汇表中的所有单词,检查是否可以使用该单词拼写出输入字符串的前缀。如果可以拼写出该前缀,则更新dp数组的值。最终,dp[L]的值就是最少需要删除的字符数。
以下是用C++实现的代码:
```cpp
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int n, L;
cin >> n >> L;
string input;
cin >> input;
vector<string> wordList(n);
for (int i = 0; i < n; ++i) {
cin >> wordList[i];
}
vector<int> dp(L + 1, 0);
for (int i = 1; i <= L; ++i) {
dp[i] = dp[i - 1] + 1; // 删除当前字符
for (int j = 0; j < n; ++j) {
int len = wordList[j].length();
if (len <= i && wordList[j] == input.substr(i - len, len)) {
dp[i] = min(dp[i], dp[i - len]);
}
}
}
cout << dp[L];
return 0;
}
```
首先,我们读取输入的真实单词数量n和输入字符串的长度L。然后,我们读取输入字符串和词汇表中的所有单词。接下来,我们创建一个大小为L+1的dp数组,并将其所有元素初始化为0。
然后,我们使用两个循环进行动态规划。外层循环遍历输入字符串的每个字符,内层循环遍历词汇表中的所有单词。我们检查当前单词是否可以拼写出输入字符串的前缀,并更新dp数组的值。在更新dp数组时,我们比较删除当前字符和使用当前单词拼写所需的删除字符数,取较小值作为dp[i]的值。
循环结束后,dp[L]的值就是最少需要删除的字符数。将其输出即可。
希望能帮到你!如果有任何疑问,请随时提问。
阅读全文