1 条题解
-
0
解题思路
数据结构选择: 使用Trie树来存储字典中的所有单词,以便快速查找前缀和完整单词。
游戏状态分析: 对于当前字母序列,我们需要: 检查是否是完整单词(长度≥) → 直接 检查是否是任何单词的前缀 → 如果不是,直接,否则,寻找可能的扩展字母
扩展字母选择策略:
首先寻找必胜扩展:选择某个字母后,无论后续如何扩展,都会在对手的回合完成单词 如果没有必胜扩展,寻找可能胜的扩展:存在至少一个单词路径会在对手的回合完成 如果都没有,选择Bluff
C++代码实现:
#include <iostream> #include <vector> #include <string> #include <set> #include <algorithm> using namespace std; set<string> dictionary; bool isWord(const string &s) { return dictionary.find(s) != dictionary.end(); } bool isPrefix(const string &s) { if (isWord(s)) return true; for (set<string>::const_iterator it = dictionary.begin(); it != dictionary.end(); ++it) { const string &word = *it; if (word.substr(0, s.size()) == s) { return true; } } return false; } char findBestExtension(const string ¤t, int numPlayers, int currentPlayer) { vector<char> winningMoves; for (char c = 'a'; c <= 'z'; ++c) { string next = current + c; if (!isPrefix(next)) continue; if (isWord(next) && next.size() >= 4) { continue; // Losing move } bool isWinning = true; for (set<string>::const_iterator it = dictionary.begin(); it != dictionary.end(); ++it) { const string &word = *it; if (word.substr(0, next.size()) == next) { int lettersLeft = word.size() - next.size(); if (lettersLeft == 0) continue; // Handled above int playerToLose = (currentPlayer + lettersLeft) % numPlayers; if (playerToLose == currentPlayer) { // Current player would lose isWinning = false; break; } } } if (isWinning) { winningMoves.push_back(c); } } if (!winningMoves.empty()) { sort(winningMoves.begin(), winningMoves.end()); return winningMoves[0]; } else { // Check if any possible move (even if not winning) for (char c = 'a'; c <= 'z'; ++c) { string next = current + c; if (isPrefix(next)) { return c; } } return '\0'; // Bluff } } int main() { int numPlayers; while (cin >> numPlayers && numPlayers >= 2) { dictionary.clear(); string line; cin.ignore(); // To skip the newline after numPlayers while (getline(cin, line)) { if (line.empty()) break; dictionary.insert(line); } string current; getline(cin, current); if (isWord(current) && current.size() >= 4) { cout << current << " Challenge" << endl; continue; } if (!isPrefix(current)) { cout << current << " Challenge" << endl; continue; } // Determine current player: assuming computer is always player 0 int currentPlayer = current.size() % numPlayers; char bestExtension = findBestExtension(current, numPlayers, currentPlayer); if (bestExtension != '\0') { cout << current << " " << bestExtension << endl; } else { cout << current << " Bluff" << endl; } } return 0; }
- 1
信息
- ID
- 1073
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 5
- 已通过
- 1
- 上传者