题目链接:POJ 2418 Hardwood Species
【题意】给出一大串树的名字,可能有重复,然后按字典序输出名字和百分比。
【思路】我已开始偷懒用了map来做,这道题给的时间是10s,用map的8s也还是水过了,真是神奇啊,后来还是写了一下字典树,700ms+就过了,效率提升显著啊。这里要注意的是建字典树的ChildSize是256,题目输入不只有字母,还有一些其它字符。
下面贴上代码,先是map的:
/*
** POJ 2418 Hardwood Species
** Created by Rayn @@ 2014/04/30
** 用map水看看
*/
#include <cstdio>
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
int main()
{
string str;
int cnt = 0;
map<string, int> tree;
while(getline(cin, str))
{
tree[str]++;
cnt++;
}
map<string, int>::iterator i;
for(i = tree.begin(); i != tree.end(); ++i)
{
cout << i->first;
printf(" %.4f\n",(i->second*100.0) / cnt);
}
return 0;
}
然后是用了字典树的:
/*
** POJ 2418 Hardwood Species
** Created by Rayn @@ 2014/05/01
** Trie树
*/
#include <cstdio>
#include <cstring>
#include <cstdlib>
const int ChildSize = 256;
int tot;
struct TrieNode {
int val; /* 用于记录单词出现的次数*/
TrieNode *child[ChildSize]; /* 分支节点的孩子指针 */
};
TrieNode *InitTrie()
{
return (TrieNode*)calloc(1, sizeof(TrieNode));
}
void Insert(TrieNode *root, char *word)
{
TrieNode *now = root;
for(char *p=word; *p; p++)
{
int v = *p;
if(now->child[v] == 0)
{
now->child[v] = (TrieNode*)calloc(1, sizeof(TrieNode));
}
now = now->child[v];
}
//到达记录统计单词次数的节点
now->val++;
}
void Search(TrieNode *root)
{
static char tmp[31];
static int pos;
if(root->val)
{
tmp[pos] = '\0';
if(tmp[0])
{
printf("%s %.4f\n", tmp, (root->val*100.0)/tot);
}
}
for(int i=0; i<256; ++i)
{
if(root->child[i])
{
tmp[pos] = i;
pos++;
Search(root->child[i]);
pos--; //回溯
}
}
}
int main()
{
char word[31];
TrieNode *root;
tot = 0;
root = InitTrie();
while(gets(word))
{
Insert(root, word);
tot++;
}
Search(root);
return 0;
}