字典树应用

1.HDU1004 Let the Balloon Rise

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 75817    Accepted Submission(s): 28455


Problem Description
Contest time again! How excited it is to see balloons floating around. But to tell you a secret, the judges' favorite time is guessing the most popular problem. When the contest is over, they will count the balloons of each color and find the result.

This year, they decide to leave this lovely job to you.
 

Input
Input contains multiple test cases. Each test case starts with a number N (0 < N <= 1000) -- the total number of balloons distributed. The next N lines contain one color each. The color of a balloon is a string of up to 15 lower-case letters.

A test case with N = 0 terminates the input and this test case is not to be processed.
 

Output
For each case, print the color of balloon for the most popular problem on a single line. It is guaranteed that there is a unique solution for each test case.
 

Sample Input
 
   
5 green red blue red red 3 pink orange pink 0
 

Sample Output
 
    
red pink

水题,刚学过字典树就用字典树做了,其实完全没有必要用字典树。

#include
using namespace std;

#define N 1000

char* input[N]={NULL};

typedef struct node{
	int count;
	bool isWord;
	node* next[26];
	node(){
		count=0;
		isWord = false;
		for(int i=0;i<26;i++){
			next[i]=NULL;
		}
	}
}*Trie;

Trie root;
//搜索,颜色没有出现过的话就插入,颜色计数++
//并且保存出现过的颜色,以便最后查找
int search(char word[]){
	if(root==NULL) root = new node;
	Trie tmp = root;
	bool isNew = false;
	for(int i=0;inext[pos]==NULL){//结点为空,说明是新单词(color)
			tmp->next[pos] = new node;
			isNew = true;
		}
		tmp = tmp->next[pos];
	}
	if(!tmp->isWord) {
		isNew = true;
		tmp->isWord = true;
	}
	tmp->count++;
	if(isNew){//新单词(color),保存到input
		for(int i=0;icount;
} 

int main(){
	int n;
	while(scanf("%d",&n)&&n){
		root = NULL;
		memset(input,NULL,sizeof(input));
		while(n--){
			char word[20];
			scanf("%s",word);
			search(word);
		}
		int max=0,flag=0;
		for(int i=0;imax){
					max = count;
					flag = i;
				}
			}else
				break;
		}
		printf("%s\n",input[flag]);
	}
	return 0;
}

注释1位置,一开始是这样写的,但是存在问题。事实上,while循环内的char word[]不会每次都重新分配,导致input里面的元素最终全部指向同一块内存,该内存空间的内容是最后输入的单词。

2. HDU1075 What Are You Talking About

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/204800 K (Java/Others)
Total Submission(s): 14229    Accepted Submission(s): 4586


Problem Description
Ignatius is so lucky that he met a Martian yesterday. But he didn't know the language the Martians use. The Martian gives him a history book of Mars and a dictionary when it leaves. Now Ignatius want to translate the history book into English. Can you help him?
 

Input
The problem has only one test case, the test case consists of two parts, the dictionary part and the book part. The dictionary part starts with a single line contains a string "START", this string should be ignored, then some lines follow, each line contains two strings, the first one is a word in English, the second one is the corresponding word in Martian's language. A line with a single string "END" indicates the end of the directory part, and this string should be ignored. The book part starts with a single line contains a string "START", this string should be ignored, then an article written in Martian's language. You should translate the article into English with the dictionary. If you find the word in the dictionary you should translate it and write the new word into your translation, if you can't find the word in the dictionary you do not have to translate it, and just copy the old word to your translation. Space(' '), tab('\t'), enter('\n') and all the punctuation should not be translated. A line with a single string "END" indicates the end of the book part, and that's also the end of the input. All the words are in the lowercase, and each word will contain at most 10 characters, and each line will contain at most 3000 characters.
 

Output
In this problem, you have to output the translation of the history book.
 

Sample Input
 
    
START from fiwo hello difh mars riwosf earth fnnvk like fiiwj END START difh, i'm fiwo riwosf. i fiiwj fnnvk! END
 


Sample Output
 
    
hello, i'm from mars. i like earth!
Hint
Huge input, scanf is recommended.

可以用字典树来解决,一开始数组开小了,导致wa,后来没加getchar()吸取换行符导致presentation error。主要是IO操作比较麻烦,scanf不要与string混用,还有gets()函数的使用要注意。

#include
using namespace std;

char dic[1000000][20];

typedef struct node{
	bool isWord;
	int num;    //记录对应的译文编号
	node* next[26];
	node(){
		isWord = false;
		num = -1;
		for(int i=0;i < 26; i++){
			next[i] = NULL;
		}
	}
}*Trie;

Trie root = NULL;

void insert(char* word,int num){
	if(root == NULL)
		root = new node();
	Trie tmp = root;
	for(int i=0;i < strlen(word);i++){
		int pos = word[i]-'a';
		if(tmp->next[pos] == NULL)
			tmp->next[pos] = new node();
		tmp = tmp->next[pos];
	}
	tmp->isWord = true;
	tmp->num = num;
}

int search(char* word){
	if(root == NULL)
		return -1;
	Trie tmp = root;
	for(int i=0;i < strlen(word);i++){
		int pos = word[i]-'a';
		if(tmp->next[pos] == NULL)
			return -1;
		tmp = tmp->next[pos];
	}
	if(tmp->isWord)
		return tmp->num;
	else return -1;
}

int main(){
	char start[] = {'S','T','A','R','T','\0'};
	char end[] = {'E','N','D','\0'};
	char str[20];
	char first[20],second[20];
	while(scanf("%s",str) && strcmp(str,start)){}
	int cnt= 0;
	while(scanf("%s",first) && strcmp(first,end)){
		scanf("%s",second);
		for(int i=0;i='a' && ch<='z'){
				target[j] = ch;
				j++;
			}else{
				if(j!=0){
					target[j]='\0';
					j=0;
					int pos=search(target);
					pos==-1?printf("%s",target):printf("%s",dic[pos]);
				}
				printf("%c",ch);
			}
			if(i==length-1){
				if(line[i]>='a'&&line[i]<='z'){
					target[j]='\0';
					j=0;
					int pos=search(target);
					pos==-1?printf("%s",target):printf("%s",dic[pos]);
				}
			}
		}//for
		printf("\n");
	}//while
	return 0;
}


你可能感兴趣的:(算法与数据结构)