cqyz oj | 旅馆

Description

  小沐几年前到德国去旅游时住过一间旅店,觉得它非常有特色,这次旅游打算还要住那里。但是他已经记不清旅店的名字了,于是他使用通配符"*"和"?"和26个小写字母来描述。注意,这里的"*"代表0个或任意多个字母,"?"代表一个字母。

  小沐在网上找到了一系列旅店的名字,他想知道有多少间旅店能与他的描述相匹配。

Input

  包含多组数据。每组数据的第一行为一个字符串,表示小沐印象中的旅店名字描述;接下来一行为一个整数n,表示在网上找到的一些旅店名字数量;再接下来的n行,每行一个字符串,表示网上提供的旅店名字。

Output

  针对每组数据,输出一个整数,表示与小沐印象中的旅店名字相匹配的网上的旅店名字的数量。

Sample Input 1

herbert
2
amazon
herbert
?ert*
2
amazon
herbert
*
2
amazon
anything
herbert?
2
amazon
herber

Sample Output 1

1
0
2
0

Hint

n<=10000 , 每个字符只由'*'和'?'和26个小写字母组成,串长度不超过50。

a[]表示印象中的描述
b[]表示搜到的旅馆
d[i][j]表示a的前i个和b的前j个能不能匹配
方程见代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 55;

char a[maxn], b[maxn];
int n, m;
bool d[maxn][maxn];
bool solve(){
    memset(d, 0, sizeof(d));
    m = strlen(b+1);
    d[0][0] = true;
    for(int i=1;i<=n;i++){
        if(a[i] == '*') d[i][0] = d[i-1][0];
        for(int j=1;j<=m;j++){
            bool t = false;
            if(a[i] == b[j] || a[i] == '?') t = t || d[i-1][j-1];
            if(a[i] == '*') t = t || d[i-1][j] || d[i][j-1];
            d[i][j] = t;
        }
    }
    return d[n][m];
}

int main(){
    int q, ans;
    while(scanf("%s", a+1) == 1){
        n = strlen(a+1);
        scanf("%d", &q);
        ans = 0;
        while(q--){
            scanf("%s", b+1);
            if(solve()) ans++;
        }
        printf("%d\n", ans);
    }
    return 0;
}
 
posted @ 2019-10-10 17:43  Deguassing-compass  阅读(122)  评论(0编辑  收藏  举报