1. 程式人生 > >UVa 11732-strcmp() Anyone?

UVa 11732-strcmp() Anyone?

由於資料規模的原因,需要用多叉樹來構建Trie,即一個結點的子樹通過一個子節點串起來,這樣節省很多空間。本程式碼的Node.count為插入時搜尋路徑經過該結點的次數,表明多少個字串在Trie相應的深度位置和當前字串裡的相應位置的字元相等,如果相等就要加上其次數乘上2,如果不相等直接加上其次數。

#include <cstdio>
#include <memory.h>
#include <cstring>
#define maxnode 4000005
#define LL long long
using namespace std;
struct Node{
	char ch;
	Node* brother;
	Node* child;
	int count;
};
Node map[maxnode];
class Trie{
public:
	Node* root;
	LL ans;
	int sz;
	void Initial(){
		sz=1;
		ans=0;
		root=NewNode(0);
	}
	Node* NewNode(char c){
		map[sz].ch=c;
		map[sz].brother=map[sz].child=NULL;
		map[sz].count=0;
		return &map[sz++];
	}
	void Trie_Insert(char str[],int n){
		Node* node=root->child,*last=root;
		bool flag;
		for(int i=0;i<=n;++i){
			flag=0;
			for(Node* next=node;next!=NULL;next=next->brother){
				if(next->ch==str[i]){
					flag=1;
					node=next;
					ans+=next->count*2;
				}else	ans+=next->count;
			}
			if(!flag){
				Node* temp=NewNode(str[i]);
				temp->brother=last->child;
				last->child=temp;
				node=temp;
			}
			node->count++;
			last=node;
			node=node->child;
		}
	}
};
int main(){
	int n,len=1;
	char str[1010];
	Trie trie;
	while(~scanf("%d",&n)){
		if(n==0)	break;
		getchar();
		trie.Initial();
		while(n--){
			gets(str);
			trie.Trie_Insert(str,strlen(str));
		}
		printf("Case %d: %lld\n",len++,trie.ans);
	}
	return 0;
}