在wordlist里随机选择一个word,调用master.match,得到匹配的个数。
假设返回值为2,那么在wordlist里,只有那些和word匹配数为2的才可能是最终的答案,可以去掉很多情况。
最优的策略是不是随机选择,这道题测试用例比较简单,随机也是能AC的。
我们的目标是尽可能减少下一次的wordlist的大小。因此,对于每一个可能的word,我们计算出以该word作为当前guess,最大的matchNum (相当于以当前word作为guess最坏的情况),并选择最小的 max_matchNum 作为最优的guess。
所以本题就是一个 Minimax 的问题。
/** * // This is the Master's API interface. * // You should not implement it, or speculate about its implementation * class Master { * public: * int guess(string word); * }; */ class Solution { public: vector<vector<int>> M; // the number of matches of wordlist[i] and wordlist[j] void findSecretWord(vector<string>& wordlist, Master& master) { int n=wordlist.size(); M.resize(n,vector<int>(n,-1)); for (int i=0;i<n;++i){ for (int j=0;j<n;++j){ int match=0; for (int k=0;k<6;++k){ if (wordlist[i][k]==wordlist[j][k]) ++match; } M[i][j] = M[j][i] = match; } } vector<int> possible; // the index of possible words for (int i=0;i<n;++i) possible.push_back(i); while (true){ int best_guess=bestGuess(possible); int matches=master.guess(wordlist[best_guess]); if (matches==6) return; vector<int> next_possible; for (int j:possible){ if (best_guess==j) continue; if (M[best_guess][j]==matches){ next_possible.push_back(j); } } possible = next_possible; } } int bestGuess(vector<int> &possible){ int min_max_matchNum=INT_MAX, best_guess; for (int guess:possible){ //matchNum[k] - the number of words that have exactly k matches with guess vector<int> matchNum(7,0); for (int j:possible){ if (guess!=j){ ++matchNum[M[guess][j]]; } } int max_matchNum=0; for (int x:matchNum) max_matchNum = max(max_matchNum, x); if (max_matchNum < min_max_matchNum){ min_max_matchNum = max_matchNum; best_guess = guess; } } return best_guess; } };