1. 程式人生 > >HDOJ 1251 統計難題(map or 字典樹)

HDOJ 1251 統計難題(map or 字典樹)

統計難題

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others)
Total Submission(s): 39360    Accepted Submission(s): 14317


Problem Description Ignatius最近遇到一個難題,老師交給他很多單詞(只有小寫字母組成,不會有重複的單詞出現),現在老師要他統計出以某個字串為字首的單詞數量(單詞本身也是自己的字首).

Input 輸入資料的第一部分是一張單詞表,每行一個單詞,單詞的長度不超過10,它們代表的是老師交給Ignatius統計的單詞,一個空行代表單詞表的結束.第二部分是一連串的提問,每行一個提問,每個提問都是一個字串.

注意:本題只有一組測試資料,處理到檔案結束.

Output 對於每個提問,給出以該字串為字首的單詞的數量.

Sample Input banana band bee absolute acm ba b band abc
Sample Output 2 3 1 0 zzuli校賽碰到一道字典樹,三個人都沒學過。。。 補補字典樹,省賽再掙扎一下。 這學期被各種事情煩死啦,打完比賽趁早滾粗。  
當然這是一道字典樹裸題,用來練手。 剛看到這題的時候,覺得map搞一搞,也可以,然後A了 程式碼如下,936ms,有點卡過
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
int main()
{
	map<string,int> mp;
	string str;
	char c;
	while(1){
		scanf("%c",&c);
		if(c=='\n')
		{
			str="";
			scanf("%c",&c);
		}
		if(c=='\n')
			break;
		str+=c;
		mp[str]++;
	}
	while((cin>>str))
	{
		printf("%d\n",mp[str]);
	}
	return 0;
} 

字典樹就是拿空間換時間了,結構很臃腫,不過時間很快 109ms 程式碼如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1e6+10;
int trie[maxn][40];
int val[maxn],temp;
char str[maxn];


void insert(char *s)
{
	int len=strlen(s);
	int u=0;
	for(int i=0;i<len;++i)
	{
		int c=s[i]-'a';
		if(!trie[u][c])
		{
			memset(trie[temp],0,sizeof(trie[temp]));
			trie[u][c]=temp++;
		}
		u=trie[u][c];
		val[u]++;
	}
}

int find(char *s)
{
	int len=strlen(s);
	int u=0;
	for(int i=0;i<len;++i)
	{
		int c=str[i]-'a';
		if(!trie[u][c])
			return 0;
		u=trie[u][c];
	}
	return val[u];
}

int main()
{
	temp=1;
	memset(trie[0],0,sizeof(trie[0]));
	memset(val,0,sizeof(val));
	while(gets(str),str[0])
	{
		insert(str);
	}
	while(scanf("%s",str)!=EOF)
	{
		printf("%d\n",find(str));
	}
	return 0;
}