题目描述:
给定n个长度不超过10的字符串以及m次询问,每次询问给出一个字符串和一个操作次数上限。
对于每次询问,请你求出给定的n个字符串中有多少个字符串可以在上限操作次数内经过操作变成询问给出的字符串。
每个对字符串进行的单个字符的插入、删除或替换算作一次操作。
输入格式
第一行包含两个整数n和m。
接下来n行,每行包含一个字符串,表示给定的字符串。
再接下来m行,每行包含一个字符串和一个整数,表示一次询问。
字符串中只包含小写字母,且长度均不超过10。
输出格式
输出共m行,每行输出一个整数作为结果,表示一次询问中满足条件的字符串个数。
数据范围
1≤n,m≤1000,
输入样例:
3 2
abc
acd
bcd
ab 1
acbd 2
输出样例:
1
3
分析:
本题可直接调用AcWing 902 最短编辑距离中的算法框架。要求n个字符串中有多少个字符串可以在给定次数内转换成指定的m个字符串,一共需要调用求最短编辑距离函数nm次,由于字符串长度不超过10,故单次求最短编辑距离复杂度为100,一共是1000*1000*100=10^8次,可以在2s内完成。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1005;
char a[maxn][10],b[maxn];
int f[maxn][maxn];
int edit(char* a,char * b){
int n = strlen(a + 1),m = strlen(b + 1);
for(int i = 0;i <= n;i++) f[i][0] = i;
for(int i = 0;i <= m;i++) f[0][i] = i;
for(int i = 1;i <= n;i++){
for(int j = 1;j <= m;j++){
if(a[i] == b[j]) f[i][j] = f[i - 1][j - 1];
else f[i][j] = min(min(f[i - 1][j],f[i][j - 1]),f[i - 1][j - 1]) + 1;
}
}
return f[n][m];
}
int main(){
int n,m,cnt;
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++) scanf("%s",a[i] + 1);
while(m--){
scanf("%s%d",b + 1,&cnt);
int ans = 0;
for(int i = 1;i <= n;i++){
if(edit(a[i],b) <= cnt) ans++;
}
printf("%d\n",ans);
}
return 0;
}