求助悬关,Trie + dfs 两种写法,一种 AC 一种 60pts
查看原帖
求助悬关,Trie + dfs 两种写法,一种 AC 一种 60pts
470960
Yellow_and_Strong楼主2023/6/2 08:35

rt

这种是 60pts 的

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1e4 + 10;
const int MAX = 21;

inline int read()
{
    int x = 0; char ch = getchar();
    while (!isdigit(ch)) ch = getchar();
    while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch xor 48), ch = getchar();
    return x;
}
inline void write (int x)
{
    if (x > 9) write(x / 10);
    putchar (x % 10 + 48);
}

int n, m; char s[MAXN][MAX];
int tot = 1, ch[MAXN * MAX][26], End[MAXN * MAX];
inline void insert (char _s[])
{
    int cur = 1;
    for (register int i = 1; i <= strlen(_s + 1); ++ i)
    {
        int val = _s[i] - 'a';
        if (!ch[cur][val]) ch[cur][val] = ++ tot;
        cur = ch[cur][val];
    }
    ++ End[cur];
}
inline void input()
{
    n = read(), m = read();
    for (register int i = 1; i <= n; ++ i)
        scanf("%s", s[i] + 1), insert(s[i]);
}

int ans, _ans, used[MAXN * MAX];
void dfs (char _s[], int now, int cur, bool flag)
{
    if (now == strlen(_s + 1) + 1)
    {
        if (End[cur] and !flag) ans = 1;
        if (End[cur] and flag and used[cur] < End[cur]) ans = min(ans, 2), ++ _ans, ++ used[cur];
        if (!End[cur] and !flag)
        {
            for (register int i = 0; i < 26; ++ i)
                if (End[ch[cur][i]] and used[ch[cur][i]] < End[ch[cur][i]]) { ans = min(ans, 2), ++ _ans, ++ used[ch[cur][i]]; break; }
        }
        return;
    }
    // if (now == strlen(_s + 1) + 1 and End[cur] and !flag) ans = 1;
    // if (now == strlen(_s + 1) + 1 and End[cur] and flag)
    // {
    //     if (used[cur] < End[cur]) ans = min(ans, 2), ++ _ans, ++ used[cur];
    //     return;
    // }

    int val = _s[now] - 'a';
    if (ch[cur][val]) dfs(_s, now + 1, ch[cur][val], flag);
    if (!flag)
    {
        if (now < strlen(_s + 1) + 1) dfs (_s, now + 1, cur, true);
        for (register int i = 0; i < 26; ++ i)
            if (ch[cur][i]) dfs(_s, now, ch[cur][i], true);
        for (register int i = 0; i < 26; ++ i)
            if (ch[cur][i] and i != val and now < strlen(_s + 1) + 1) dfs(_s, now + 1, ch[cur][i], true);
    }
    // if (now >= strlen(_s + 1) + 1) return;
}
inline void work()
{
    while (m --)
    {
        char _s[MAX]; scanf("%s", _s + 1);
        ans = 3, _ans = 0, memset(used, false, sizeof(used));
        dfs(_s, 1, 1, false);
        if (ans == 1) puts("-1");
        else if (ans == 2) write(_ans), putchar('\n');
        else puts("0");
    }
}

int main()
{
    input();
    work();
    return 0;
}

这种是 AC 的

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1e4 + 10;
const int MAX = 21;

inline int read()
{
    int x = 0; char ch = getchar();
    while (!isdigit(ch)) ch = getchar();
    while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch xor 48), ch = getchar();
    return x;
}
inline void write (int x)
{
    if (x > 9) write(x / 10);
    putchar (x % 10 + 48);
}

int n, m; char s[MAXN][MAX];
int tot = 1, ch[MAXN * MAX][26], End[MAXN * MAX];
inline void insert (char _s[])
{
    int cur = 1;
    for (register int i = 1; i <= strlen(_s + 1); ++ i)
    {
        int val = _s[i] - 'a';
        if (!ch[cur][val]) ch[cur][val] = ++ tot;
        cur = ch[cur][val];
    }
    ++ End[cur];
}
inline void input()
{
    n = read(), m = read();
    for (register int i = 1; i <= n; ++ i)
        scanf("%s", s[i] + 1), insert(s[i]);
}

int ans, _ans, used[MAXN * MAX];
void dfs (char _s[], int now, int cur, bool flag)
{
    // if (now == strlen(_s + 1) + 1)
    // {
    //     if (End[cur] and !flag) ans = 1;
    //     if (End[cur] and flag and used[cur] < End[cur]) ans = min(ans, 2), ++ _ans, ++ used[cur];
    //     if (!End[cur] and !flag)
    //     {
    //         for (register int i = 0; i < 26; ++ i)
    //             if (End[ch[cur][i]] and used[ch[cur][i]] < End[ch[cur][i]]) { ans = min(ans, 2), ++ _ans, ++ used[ch[cur][i]]; break; }
    //     }
    //     return;
    // }
    if (now == strlen(_s + 1) + 1 and End[cur] and !flag) ans = 1;
    if (now == strlen(_s + 1) + 1 and End[cur] and flag)
    {
        if (used[cur] < End[cur]) ans = min(ans, 2), ++ _ans, ++ used[cur];
        return;
    }

    int val = _s[now] - 'a';
    if (ch[cur][val]) dfs(_s, now + 1, ch[cur][val], flag);
    if (!flag)
    {
        if (now < strlen(_s + 1) + 1) dfs (_s, now + 1, cur, true);
        for (register int i = 0; i < 26; ++ i)
            if (ch[cur][i]) dfs(_s, now, ch[cur][i], true);
        for (register int i = 0; i < 26; ++ i)
            if (ch[cur][i] and i != val and now < strlen(_s + 1) + 1) dfs(_s, now + 1, ch[cur][i], true);
    }
    if (now >= strlen(_s + 1) + 1) return;
}
inline void work()
{
    while (m --)
    {
        char _s[MAX]; scanf("%s", _s + 1);
        ans = 3, _ans = 0, memset(used, false, sizeof(used));
        dfs(_s, 1, 1, false);
        if (ans == 1) puts("-1");
        else if (ans == 2) write(_ans), putchar('\n');
        else puts("0");
    }
}

int main()
{
    input();
    work();
    return 0;
}
2023/6/2 08:35
加载中...