1 条题解
-
0
分组策略:将前 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
- 上传者