字典树60pts求调,hack数据全过
查看原帖
字典树60pts求调,hack数据全过
759274
Stevehim楼主2023/10/27 09:43
#include <bits/stdc++.h>
// #define int long long
#define maxn 2000100
#define maxm 5010
#define endl '\n'
using namespace std;
//输了你,禁赛三年又如何
struct Trie{
    int nxt[maxm][30], cnt;
    bool exist[maxn];
    void ins(char *s, int l){
        int p = 0;
        for(int i = 0; i < l; i++){
            int c = s[i] - 'a';
            if(!nxt[p][c]) nxt[p][c] = ++cnt;
            p = nxt[p][c];
        }
        exist[p] = true;
    }
    int find(char *s,int pos,int l){ //考虑进行dfs类似的  //pos:当前进来的位置,l:当前字符串长度
        int p = 0; //从根节点进行搜索
        int ans = pos, i;
        if(pos == l) return pos; //其实说明跑完了
        for(i = pos; i <= l; i++){
            int c = s[i] - 'a';
            if(!nxt[p][c] && p == 0 && i == pos){ //说明这种情况走不下去
              return pos - 1; //传来的pos相当于之前的前缀长度 + 1,如果当前一个也匹配不上,返回值应直接返回pos - 1(原值,因为前缀指的是一个一个单词)
            }
            if(!nxt[p][c] && p != 0){ //说明往下走了
                if(exist[p] && i != l) {//说明这个单词没了并且当前串没走完
                    ans = i; //记录
                    break;
                }
                if(exist[p] && i == l){ //p在后面更新答案
                    return l; //正好匹配完,返回l
                }
                ans = max(ans, find(s, i, l)); //进行比较
                return pos - 1; //只能走这么多了
            }
            p = nxt[p][c];
        }
        return max(ans, find(s, i, l));
    }
}trie;
int n, m;
char ch[maxn];

int main(){
    freopen("1.in","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cin >> n >> m;
    for(int i = 1; i <= n; i++){
        cin >> ch;
        trie.ins(ch, strlen(ch));
    }
    for(int i = 1; i <= m; i++){
        cin >> ch;
        int num = trie.find(ch, 0, strlen(ch));
        if(num == -1) cout << 0 << endl;
        else cout << num << endl;
    }   
    return 0;
}
2023/10/27 09:43
加载中...