Problem address: http://cstfs.gdufs.edu.cn: 8080/judgeonline/problem. jsp? Id = 1127
[Preface]
A question for the school's OJ competition.
It seems to be from usaco.
During the competition, we thought about the dictionary tree, the AC automatic machine, and the addition of DP.
After the game, I read the code with a few eyes. The teacher said it was DP, and the problem-solving report hasn't come out yet.
[Idea]
Since the word length is only 20, you can write an article here.
Returns the minimum alphabetic result from the current position with 20 strings.
Then, all words are enumerated for each position of the original string.
If the words with the length of Len can match, update the current position and add the string corresponding to Len.
An update attempt indicates that a string that is larger than a string cannot be updated.
After one position is enumerated, all strings are cyclically moved to 1. That is, Move 2 to 1, 3 to 2 ...... 20 to 19, and 1 to 20.
Then the next position is determined.
If the current position is an empty string, it cannot be updated, but it still needs to be moved.
Note 1: Enumerate all words and save the result to an array of 20 characters. Then, we enumerate this array to update 20 strings and reduce the complexity by reducing repeated string comparisons.
NOTE 2: 20 strings can be saved with pointers, so you only need to move the pointer when moving. Of course, it can also be replaced by a modulo.
[Code]
Add a case to the code.
After sample but wa, a case is written. After comparison, we found that there was only one more line of code =.
#include <iostream>#include <algorithm>using namespace std;const int maxn = 1030;const int INF = 1000000;const int kind = 20;/*20 5a??ple??????????ple?pleeeplefabcapleabcpleeeabcabceaplee*/struct node{char w[kind+5];int len;}words[maxn+5];bool cmp(const node &a, const node &b){int t = strcmp(a.w, b.w);if (t<0) return true;else return false;}char org[maxn+5];int tre[kind+5];char *str[kind+5];char strtemp[kind+5][maxn+5];char *temp;bool match(char *str, int s, int n, int len){if (s+len>n) return false;int i;for (i=0; i<len; i++){if (org[s+i]!='?' && org[s+i]!=str[i])return false;}return true;}int main(){int i, j;int n, m;scanf("%d %d", &n, &m);scanf("%s", org);for (i=0; i<m; i++){scanf("%s", words[i].w);words[i].len = strlen(words[i].w);}sort(words, words+m, cmp);memset(strtemp, 0, sizeof(strtemp));for (i=1; i<=kind; i++) str[i] = strtemp[i];str[1][0] = '\0';for (i=0; i<n; i++){if (i==0 || str[1][0]!='\0'){for (j=0; j<=kind; j++) tre[j] = INF;for (j=0; j<m; j++){if (j<tre[words[j].len] && match(words[j].w, i, n, words[j].len)){tre[words[j].len] = j;}}temp = str[1];for (j=1; j<kind; j++){str[j] = str[j+1];}for (j=1; j<kind; j++){if (tre[j]==INF){continue;}strcat(temp, words[tre[j]].w);if (tre[j]!=INF && (str[j][0]=='\0' || strcmp(temp, str[j])<0)){strcpy(str[j], temp);}temp[i] = '\0';}str[kind] = temp;if (tre[kind]!=INF){strcat(str[kind], words[tre[kind]].w);}else str[kind][0] = '\0';}else{temp = str[1];for (j=1; j<kind; j++) str[j] = str[j+1];str[kind] = temp;}}printf("%s\n", str[1]);return 0;}