先排序,排完序后前缀相同的会相邻,然后遍历。 #include<stdio.h> #include<string.h> #include<stdlib.h> #define MAXLENGTH 101 #define MAXWORDS 1000 //priority queue #define SCENARIO "Scenario #%d:/n" struct Word { char *str; int p; bool removed; }; void printStr(char *str, int length) { for (int i = 0; str[i] && i < length; i++) printf("%c", str[i]); printf("/n"); } void swap(Word *a, Word *b) { Word c = *a; *a = *b; *b = c; } int cmp(Word *a, Word *b) { return strcmp(a->str, b->str); } bool strcmp2(char *s1, char *s2, int len) { for (int i = 0; i < len; i++) if (s1[i] != s2[i] || s1[i] == '/0' || s2[i] == '/0') return false; return true; } int partion(Word *arr, int p, int r) { int i = p - 1; for (int j = p; j < r; j++) { if (cmp(arr + j, arr + r) <= 0) { i++; swap(arr + i, arr + j); } } swap(arr + i + 1, arr + r); return i + 1; } void quicksort(Word *arr, int p, int r) { if (p < r) { int q = partion(arr, p, r); quicksort(arr, p, q - 1); quicksort(arr, q + 1, r); } } bool checkLetter(int digit, char ch) { switch(digit) { case '2': return (ch == 'a' || ch == 'b' || ch == 'c'); case '3': return (ch == 'd' || ch == 'e' || ch == 'f'); case '4': return (ch == 'g' || ch == 'h' || ch == 'i'); case '5': return (ch == 'j' || ch == 'k' || ch == 'l'); case '6': return (ch == 'm' || ch == 'n' || ch == 'o'); case '7': return (ch == 'p' || ch == 'q' || ch == 'r' || ch == 's'); case '8': return (ch == 't' || ch == 'u' || ch == 'v'); case '9': return (ch == 'w' || ch == 'x' || ch == 'y' || ch == 'z'); } return false; } void solve() { int w, p, m; //w: 1000 limit, scanf("%d/n", &w); Word words[MAXWORDS]; memset(words, 0, sizeof(Word) * MAXWORDS); for (int i = 0; i < w; i++) { words[i].str = (char*)calloc(MAXLENGTH, sizeof(char)); scanf("%s", words[i].str); scanf("%d", &words[i].p); } quicksort(words, 0, w - 1); scanf("%d/n", &m); for (int i = 0; i < m; i++) { char digits[MAXLENGTH] = {'/0'}; scanf("%s/n", digits); for (int j = 0; j < w; j++) words[j].removed = false; for (int j = 0; digits[j] && digits[j] != '1'; j++) { int maxP = -1; int maxW = -1; int currentP = 0; int k = 0; while (k < w) { if (words[k].str[j] != '/0' && checkLetter(digits[j], words[k].str[j]) && !words[k].removed) { currentP = words[k].p; while(true) { k++; if (k < w && strcmp2(words[k - 1].str, words[k].str, j + 1)) currentP += words[k].p; else break; } if (maxP < currentP) { maxP = currentP; maxW = k - 1; } } else { words[k].removed = true; k++; } } if (maxW >= 0) printStr(words[maxW].str, j + 1); else printf("MANUALLY/n"); } printf("/n"); } } int main() { #ifndef ONLINE_JUDGE freopen("data.txt", "r", stdin); #endif int s; scanf("%d/n", &s); for (int i = 0; i < s; i++) { printf(SCENARIO, i + 1); solve(); printf("/n"); } #ifndef ONLINE_JUDGE fclose(stdin); #endif }