云计算百科
云计算领域专业知识百科平台

打卡信奥刷题(3671)用C++实现信奥题 P12238 [蓝桥杯 2023 国 Java A] 单词分类

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */
#content_views .toc,
/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */
#content_views.markdown_views > p:empty:has(+ .toc),
#content_views.markdown_views > .toc + p:empty,
/* 富文本旧版目录标记 */
#content_views.htmledit_views #main-toc,
#content_views.htmledit_views #hr-toc,
#content_views.htmledit_views p[id*=\”-toc\”] {
display: none !important;
}
/* 目录去掉后,紧跟的首个标题不再多出一块上边距 */
#content_views.markdown_views > .toc + h1,
#content_views.markdown_views > .toc + h2,
#content_views.markdown_views > .toc + h3,
#content_views.markdown_views > .toc + h4,
#content_views.markdown_views > .toc + p:empty + h1,
#content_views.markdown_views > .toc + p:empty + h2,
#content_views.markdown_views > .toc + p:empty + h3,
#content_views.markdown_views > .toc + p:empty + h4 {
margin-top: 0 !important;
}

P12238 [蓝桥杯 2023 国 Java A] 单词分类

题目描述

在遥远的 LQ 国,只存在三种字符:l\\tt{l}l、q\\tt{q}q 和 b\\tt{b}b(ASCII 码分别为 108108108、113113113、989898),所有的单词都由这三种字符组合而来。小蓝为了更加快速的记忆单词,决定将词典上所有的单词按照单词前缀将其分为 KKK 类,具体的要求是:

  • 选出 KKK 个不同的单词前缀作为 KKK 类(空串也是合法的单词前缀);
  • 对于字典上的每个单词,只能属于 KKK 类中的某一个类,不能同时属于多个类,也不能不属于任何一类;
  • 对于 KKK 类中的每个类,至少包含有一个单词。
  • 现在已知字典上一共有 NNN 个单词,小蓝想要知道将这 NNN 个单词按照上述要求分为 KKK 类,一共有多少种不同的方案。两个方案不同指的是两个方案各自选出的 KKK 个单词前缀不完全相同。答案可能过大,所以你需要将答案对 1 000 000 0071\\,000\\,000\\,0071000000007(即 109+710^9 + 7109+7)取模后输出。

    输入格式

    输入的第一行包含两个整数 NNN 和 KKK;

    接下来 NNN 行,每行包含一个单词,由 l\\tt{l}l、q\\tt{q}q、b\\tt{b}b 三种字符组成。

    输出格式

    输出一个整数表示答案。答案可能很大,请输出答案对 1 000 000 0071\\,000\\,000\\,0071000000007 取模的值。

    输入输出样例 #1

    输入 #1

    4 2
    lqb
    lql
    qqq
    qql

    输出 #1

    4

    说明/提示

    样例说明

    • 方案 1:l=lqb,lql\\tt{l}=\\tt{lqb}, \\tt{lql}l=lqb,lql、q=qqq,qql\\tt{q}=\\tt{qqq}, \\tt{qql}q=qqq,qql;
    • 方案 2:lq=lqb,lql\\tt{lq}=\\tt{lqb}, \\tt{lql}lq=lqb,lql、q=qqq,qql\\tt{q}=\\tt{qqq}, \\tt{qql}q=qqq,qql;
    • 方案 3:l=lqb,lql\\tt{l}=\\tt{lqb}, \\tt{lql}l=lqb,lql、qq=qqq,qql\\tt{qq}=\\tt{qqq}, \\tt{qql}qq=qqq,qql;
    • 方案 4:lq=lqb,lql\\tt{lq}=\\tt{lqb}, \\tt{lql}lq=lqb,lql、qq=qqq,qql\\tt{qq}=\\tt{qqq}, \\tt{qql}qq=qqq,qql。

    以方案 111 为例,他表示选出的两类对应的前缀分别是 l\\tt ll 和 q\\tt qq,属于前缀 l\\tt ll 的单词有 lqb\\tt {lqb}lqb、lql\\tt{lql}lql,属于前缀 q\\tt qq 的单词有 qqq\\tt{qqq}qqq、qql\\tt{qql}qql,方案 111 将四个单词按照前缀分成了两类,且每类至少包含一个单词,每个单词仅属于一类,所以方案 111 满足题意。

    评测用例规模与约定

    • 对于 30%30\\%30% 的评测用例,1≤N≤101 \\leq N \\leq 101≤N≤10,1≤K≤51 \\leq K \\leq 51≤K≤5;
    • 对于 50%50\\%50% 的评测用例,1≤N≤501 \\leq N \\leq 501≤N≤50,1≤K≤101 \\leq K \\leq 101≤K≤10;
    • 对于所有评测用例,1≤N≤2001 \\leq N \\leq 2001≤N≤200,1≤K≤1001 \\leq K \\leq 1001≤K≤100,1≤1 \\leq1≤ 单词长度 ≤10\\leq 10≤10。

    C++实现

    #include"bits/stdc++.h"
    using namespace std;
    const int N = 205 * 10, K = 105, mod = 1e9 + 7;
    int n, k;
    int trie[N][4], word[N], tot;
    vector<int>g[N];
    inline int get_num(char c) {
    if (c == 'l')return 1;
    if (c == 'q')return 2;
    return 3;
    }
    void insert(string s) {
    int u = 0;
    for (char c : s) {
    int a = get_num(c);
    if (!trie[u][a]) {
    trie[u][a] = ++tot;
    g[u].push_back(tot);//建图
    }
    u = trie[u][a];
    }
    word[u]++;
    }
    long long dp[N][K];
    void dfs(int u) {
    if (u && word[u]) {//叶子节点
    dp[u][1] = 1;
    return;
    }
    dp[u][0] = 1;//初始状态
    for (int v : g[u]) {
    dfs(v);
    long long t[K] = {0};//临时数组存储结果,避免计算时新计算的值影响后面的计算
    for (int i = 0; i <= k; i++) {
    for (int j = 0; j <= k – i; j++) {
    t[i + j] = (t[i + j] + dp[u][i] * dp[v][j]) % mod;//枚举计算
    }
    }
    memcpy(dp[u], t, sizeof dp[u]);//赋值回来
    }
    dp[u][1] = (dp[u][1] + 1) % mod;//单独选择该节点
    }
    signed main() {
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);
    cin >> n >> k;
    for (int i = 1; i <= n; i++) {
    string s;
    cin >> s;
    insert(s);//建 Trie 树
    }
    dfs(0);//树形 DP
    cout << dp[0][k];
    return 0;
    }

    在这里插入图片描述

    后续

    接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 打卡信奥刷题(3671)用C++实现信奥题 P12238 [蓝桥杯 2023 国 Java A] 单词分类
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!