首先,程序是无文件版本的。所以用的是读入版。(USACO莫名的登陆不鸟了)
字母树保存名单,然后直接穷举情况,遍历字母树即可。
/* ID:xueyifa4 PROG:namenum LANG:C++ */ #include <iostream> #include <cstdio> #include <cstring> using namespace std; FILE *dict = fopen("dict.txt", "r"); FILE *in = fopen("namenum.in", "r"); FILE *out = fopen("namenum.out", "w"); char _name[12]; char _number[15]; bool flag(false); int term[20][3] = { {0, 0, 0}, {0, 0, 0}, {0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10 ,11}, {12, 13, 14}, {15, 17, 18}, {19, 20, 21}, {22, 23, 24}}; class point { public: point *a[26]; bool flag; point() { for (int i = 0; i != 26; ++ i) a[i] = NULL; flag = false; } }root; void insert(point &t, char *s, int k, int length)//插入单词 root, 字符串, 第k个字符, 字符串长度 { if (k == length) { t.flag = true; //t这个节点为一个单词 return; } int num = s[k] - 'A'; if (t.a[num] == NULL) t.a[num] = new point; insert(*t.a[num], s, k + 1, length); } void dfs(int k, int number_length, char *number, char *name, point &T)//第k个位置填写的字母, 编号长度, 编号数组, 字母数组, 当前节点 { if (k == number_length) { if (!T.flag) return; flag = true; for (int i = 0; i != k; ++ i) printf("%c", name[i]); printf("\n"); return; } int num = number[k] - '0'; if (num < 2) return; for (int t = 0; t != 3; ++ t)//对应的是i这个单词 { int i = term[num][t]; if (T.a[i] == NULL) continue; name[k] = i + 'A'; dfs(k + 1, number_length, number, name, *T.a[i]); } } char tmp_s[100]; int main() { for (int i = 1; i <= 24829; ++ i) { scanf("%s", tmp_s); insert(root, tmp_s, 0, strlen(tmp_s)); } scanf("%s", _number); dfs(0, strlen(_number), _number, _name, root); if (!flag) printf("NONE\n"); return 0; }
直接读入名字,判断这个名字对应的数字,因为字典就是字典序,所以直接判断一个输出一个即可。程序会非常短