直接暴力也可,用的二分搜索+枚举,文件输入的调试了很久,后来不知道怎么就对了。
二分的是写成求最小符合条件的下标;/*PROG: namenumLANG: C++*/# include# include # include # define N 5000 + 10# define LEN 20int len[N];char s[N][LEN];char tab[30];void build(void){ for (int i = 'A'; i < 'S'; ++i) tab[i - 'A'] = (i-'A') / 3 + 2 + '0'; tab['S'-'A'] = '7'; for (int i = 0; i < 7; ++i) tab[i + 'T'-'A'] = i / 3 + 8 + '0'; tab['Q'-'A'] = tab['Z'-'A'] = '*';}int cmp(const void *xx, const void *yy){ char *x = (char *)xx; char *y = (char *)yy; int lenx = strlen(x), leny = strlen(y); if (lenx == leny) return strcmp(x, y); return lenx - leny;}int sideBsearch(int x, int *v, int n){ int low, high, mid; low = 0, high = n - 1; while (low < high) { mid = low + (high-low)/2; if (v[mid] >= x) high = mid; else low = mid + 1; } if (v[low] == x) return low; else return -1;}void mapToNum(char *name, char *s){ int i; for (i = 0; name[i]; ++i) s[i] = tab[name[i]-'A']; s[i] = '\0';}int main(){ FILE *fdic = fopen("dict.txt", "r"); FILE *fin = fopen("namenum.in", "r"); FILE *fout = fopen("namenum.out", "w"); build(); int n = 0; while (EOF != fscanf(fdic, "%s\n", s[n])) ++n; fclose(fdic); qsort(s, n, sizeof(s[0]), cmp); for (int i = 0; i < n; ++i) len[i] = strlen(s[i]); char id[LEN], buf[LEN]; fscanf(fin, "%s", id), fclose(fin); int lenid = strlen(id), cnt = 0; int i = sideBsearch(lenid, len, n); if (i >= 0) for (int j = i; len[j] == lenid; ++j) { mapToNum(s[j], buf); if (strcmp(buf, id) == 0) {fprintf(fout, "%s\n", s[j]); ++cnt;} } if (cnt == 0) fprintf(fout, "NONE\n"); fclose(fout); return 0;}
/**/