USACO Letter Game 解题报告

来源:互联网 发布:项目数据分析师 上海 编辑:程序博客网 时间:2024/05/21 17:29

这道题比较简单,虽然我还是用了很久(多半天)。我没有看到每个word至少含有3个字符这个条件,所以应该多测试了些无用的情况。但是考虑到答案用的是穷举,所以很快(指程序运行时间)过了也没什么奇怪的。这里用字典建了一个trie,然后遍历各种可能,剪掉在trie中查不到的。考虑到一个单词形成过程中会被我在trie中反复查,如果我比穷举的方法慢的话也不足为奇。

/* ID: thestor1 LANG: C++ TASK: lgame */#include <iostream>#include <fstream>#include <cmath>#include <cstdio>#include <cstring>#include <climits>#include <cassert>#include <string>#include <vector>#include <set>#include <map>#include <queue>#include <stack>#include <algorithm>using namespace std;struct Trie {int completed;Trie* next[26];Trie(){for (int i = 0; i < 26; ++i){next[i] = NULL;}completed = 0;}};void insert(Trie *trie, string str){for (int i = 0; i < str.size(); ++i){if (!trie->next[str[i] - 'a']){trie->next[str[i] - 'a'] = new Trie();}trie = trie->next[str[i] - 'a'];if (trie->completed == 0){trie->completed = 1;}}trie->completed = 2;}int search(Trie *trie, string str){for (int i = 0; i < str.size(); ++i){if (!trie->next[str[i] - 'a']){return false;}trie = trie->next[str[i] - 'a'];}return trie->completed;}Trie *trie;std::vector<int> values(26, 0);bool byvalues(const char &c1, const char &c2){return values[c1 - 'a'] > values[c2 - 'a'];}void update(string word, bool hasone, string before, int score, int &maxscore, map<string, int> &candidates){if (score > maxscore){maxscore = score;}if (score == maxscore){if (hasone){if (before <= word){before.push_back(' ');word = before + word;candidates[word] = score;}}else{candidates[word] = score;}}}void lettergame(string letters, std::vector<bool> visited, string word, bool hasone, string before, int score, int &maxscore, map<string, int> &candidates){if (hasone && word.size() == 1 && word[0] < before[0]){return;}for (int i = 0; i < visited.size(); ++i){// cout<<"[debug]word:"<<word<<", score:"<<score<<endl;if (visited[i]){continue;}visited[i] = true;word.push_back(letters[i]);score += values[letters[i] - 'a'];int s = search(trie, word);if (s == 2){update(word, hasone, before, score, maxscore, candidates);if (!hasone){lettergame(letters, visited, "", true, word, score, maxscore, candidates);}}if (s > 0){lettergame(letters, visited, word, hasone, before, score, maxscore, candidates);}score -= values[letters[i] - 'a'];word = word.substr(0, word.size() - 1);visited[i] = false;}}int main(){ifstream fin("lgame.in");ofstream fout("lgame.out");string letters;getline(fin, letters);// cout<<"["<<letters<<"]"<<endl;values[0] = 2; // a : 2values[1] = 5; // b : 5values[2] = 4; // c : 4values[3] = 4; // d : 4values[4] = 1; // e : 1values[5] = 6; // f : 6values[6] = 5; // g : 5values[7] = 5; // h : 5values[8] = 1; // i : 1values[9] = 7; // j : 7values[10] = 6; // k : 6values[11] = 3; // l : 3values[12] = 5; // m : 5values[13] = 2; // n : 2values[14] = 3; // o : 3values[15] = 5; // p : 5values[16] = 7; // q : 7values[17] = 2; // r : 2values[18] = 1; // s : 1values[19] = 2; // t : 2values[20] = 4; // u : 4values[21] = 6; // v : 6values[22] = 6; // w : 6values[23] = 7; // x : 7values[24] = 5; // y : 5values[25] = 7; // z : 7// sort(letters.begin(), letters.end(), byvalues);trie = new Trie();ifstream dictfile("lgame.dict");while (true){string word;getline(dictfile, word);if (word == "."){break;}insert(trie, word);}int maxscore = 0;map<string, int> candidates;lettergame(letters, std::vector<bool>(letters.size(), false), "", false, "", 0, maxscore, candidates);// cout<<maxscore<<endl;fout<<maxscore<<endl;// std::vector<string> words;for (map<string, int>::iterator iter = candidates.begin(); iter != candidates.end(); ++iter){if (iter->second == maxscore){// cout<<iter->first<<endl;fout<<iter->first<<endl;// words.push_back(iter->first);}}// sort(words.begin(), words.end());// for (int i = 0; i < words.size(); ++i)// {// fout<<words[i]<<endl;// }fin.close();fout.close();return 0;  }




0 0