您的位置:首页 > 其它

USACO Letter Game 解题报告

2014-08-07 05:32 337 查看
这道题比较简单,虽然我还是用了很久(多半天)。我没有看到每个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 : 2
values[1] = 5; // b : 5
values[2] = 4; // c : 4
values[3] = 4; // d : 4
values[4] = 1; // e : 1
values[5] = 6; // f : 6
values[6] = 5; // g : 5
values[7] = 5; // h : 5
values[8] = 1; // i : 1
values[9] = 7; // j : 7
values[10] = 6; // k : 6
values[11] = 3; // l : 3
values[12] = 5; // m : 5
values[13] = 2; // n : 2
values[14] = 3; // o : 3
values[15] = 5; // p : 5
values[16] = 7; // q : 7
values[17] = 2; // r : 2
values[18] = 1; // s : 1
values[19] = 2; // t : 2
values[20] = 4; // u : 4
values[21] = 6; // v : 6
values[22] = 6; // w : 6
values[23] = 7; // x : 7
values[24] = 5; // y : 5
values[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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: