1 条题解

  • 0
    @ 2025-5-11 21:45:25

    解题思路

    数据结构选择: 使用Trie树来存储字典中的所有单词,以便快速查找前缀和完整单词。

    游戏状态分析: 对于当前字母序列,我们需要: 检查是否是完整单词(长度≥44) → 直接ChallengeChallenge 检查是否是任何单词的前缀 → 如果不是,直接ChallengeChallenge,否则,寻找可能的扩展字母

    扩展字母选择策略

    首先寻找必胜扩展:选择某个字母后,无论后续如何扩展,都会在对手的回合完成单词 如果没有必胜扩展,寻找可能胜的扩展:存在至少一个单词路径会在对手的回合完成 如果都没有,选择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 &current, 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
    上传者