1 条题解

  • 0
    @ 2025-5-25 19:42:16

    分组策略:将前 L 个大写字母(A-L)分成 B 组,每组至少 1 个字符。分组方式为连续字符段,例如:A-C 为一组,D-F 为一组,依此类推。哈希计算:对于每个分组方案,将每个字符映射到其所在组的编号。使用修改后的哈希函数计算每个单词的哈希值其中,map[c]为字符 c 所在的组编号。去重统计:使用哈希表统计每个哈希值出现的次数。计算唯一哈希值的数量(即出现次数为 1 的哈希值数量)。回溯搜索:使用 DFS 枚举所有可能的分组方案,记录最大唯一哈希值数量及其对应的分组方案。

    #include <stdio.h>
    #include <string.h>
    
    #define MAX_D 1024
    #define HASH_SIZE 65536
    
    struct node {
        struct node *next;
        int val, cnt;
    };
    
    int B, L, D;
    int map[256], ans[256], best;
    char dict[MAX_D][16];
    struct node nodes[MAX_D], *hash[HASH_SIZE];
    int nodes_cnt;
    int vis[HASH_SIZE], tm;
    
    inline void calc()
    {
        int i, h, val, uni;
        char *s;
        struct node *t;
    
        tm++;
        nodes_cnt = 0;
        for (i = 0; i < D; i++) {
            val = 0;
            for (s = dict[i]; *s; s++) 
                val = val*31 + map[*s] + 'a';
            h = val & (HASH_SIZE - 1);
            if (vis[h] != tm) {
                vis[h] = tm;
                hash[h] = NULL;
            }
            for (t = hash[h]; t; t = t->next)
                if (t->val == val)
                    break;
            if (!t) {
                t = &nodes[nodes_cnt++];
                t->val = val;
                t->cnt = 0;
                t->next = hash[h];
                hash[h] = t;
            }
            t->cnt++;
        }
    
        uni = 0;
        for (i = 0; i < nodes_cnt; i++)
            if (nodes[i].cnt == 1)
                uni++;
    
        if (uni > best) {
            best = uni;
            memcpy(ans, map, sizeof(map));
        }
    }
    
    void dfs(int b, int l)
    {
        int i, cnt;
    
        cnt = L - l - (B - b) + 1;
        for (i = 0; i < cnt; i++)
            map[l + 'A' + i] = b;
        
        if (b == B - 1) {
            calc();
            return ;
        }
    
        for (i = cnt; i >= 1; i--)
            dfs(b + 1, l + i);
    }
    
    int main()
    {
        int i;
    
        freopen("e:\\test\\in.txt", "r", stdin);
    
        scanf("%d%d%d", &B, &L, &D);
        for (i = 0; i < D; i++)
            scanf("%s", dict[i]);
        dfs(0, 0);
        printf("%d\n", best);
        for (i = 'A'; i < 'A' + L; i++) {
            if (ans[i] != ans[i - 1])
                putchar('\n');
            putchar(i);
        }
        putchar('\n');
    
        return 0;
    }
    
    
    • 1

    信息

    ID
    2189
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    9
    已通过
    1
    上传者