↓ Skip to main content
  1. Posts/

poj 2001 Shortest Prefixes (trie树)

·575 words·2 mins
Note: This article is available in Chinese only. 本文暂无英文版本。 View original

poj 2001 题目链接

题意:给出n个字符串的表,问每个字符串的简化表示。简化表示的要求是,以该字符串的最短的而且不能产生歧义的前缀来表示。

思路:字典树,多一个cnt属性,每次insert的时候,路过的每个节点的cnt++

find的时候从root往下扫。。遇到的cnt为1的节点结尾的字符串。。就是该单词的唯一表示。。。

按照这个思路写了一发。。。1A好开心哈哈哈

代码实现
  1/* ***********************************************
  2Author :111qqz
  3Created Time :2016年08月16日 星期二 02时55分22秒
  4File Name :code/poj/2001.cpp
  5************************************************ */
  6#include <cstdio>
  7#include <cstring>
  8#include <iostream>
  9#include <algorithm>
 10#include <vector>
 11#include <queue>
 12#include <stack>
 13#include <set>
 14#include <map>
 15#include <string>
 16#include <cmath>
 17#include <cstdlib>
 18#include <deque>
 19#include <ctime>
 20#define fst first
 21#define sec second
 22#define lson l,m,rt<<1
 23#define rson m+1,r,rt<<1|1
 24#define ms(a,x) memset(a,x,sizeof(a))
 25typedef long long LL;
 26#define pi pair < int ,int >
 27#define MP make_pair
 28using namespace std;
 29const double eps = 1E-8;
 30const int dx4[4]={1,0,0,-1};
 31const int dy4[4]={0,-1,1,0};
 32const int inf = 0x3f3f3f3f;
 33const int N=1E3+7;
 34char s[N][25];
 35int n;
 36struct Trie
 37{
 38    struct Node
 39    {
 40	Node *nxt[26];
 41	int cnt;
 42	Node()
 43	{
 44	    for ( int i = 0 ; i < 26;  i++) nxt[i] = NULL;
 45	    cnt = 0 ;
 46	}
 47    };
 48    Node *root;
 49    void init()
 50    {
 51	root = new Node();
 52    }
 53    Trie()
 54    {
 55	root = new Node();
 56    }
 57    void Insert(char *s)
 58    {
 59	Node *u = root;
 60	int len = strlen(s);
 61	for ( int i = 0 ; i < len ; i++)
 62	{
 63	    int v = s[i]-'a';
 64	    if (u->nxt[v]==NULL) u->nxt[v] = new Node();
 65	    u = u->nxt[v];
 66	    u->cnt++;
 67	}
 68    }
 69    string Find(char *s)
 70    {
 71	Node *u = root;
 72	string res="";
 73	int len = strlen(s);
 74	for ( int i = 0 ; i < len ; i++)
 75	{
 76	    int v = s[i]-'a';
 77	    res = res + s[i];
 78	    u = u->nxt[v];
 79	    if (u->cnt==1) return res; //cnt为1表示应该就唯一了吧。。。
 80	}
 81    }
 82}trie;
 83int main()
 84{
 85	#ifndef  ONLINE_JUDGE
 86	freopen("code/in.txt","r",stdin);
 87  #endif
 88	n = 0 ;
 89	trie.init();
 90	while (~scanf("%s",s[n++]));
 91	n--;
 92	for ( int i = 0 ; i <n ; i++)
 93	{
 94	    //cout<<"i:"<<i<<" s[i]:"<<s[i]<<endl;
 95	    trie.Insert(s[i]);
 96	}
 97	for ( int i = 0 ; i < n ; i++)
 98	{
 99	    string ans = trie.Find(s[i]);
100	    cout<<s[i]<<" "<<ans<<endl;
101	}
102  #ifndef ONLINE_JUDGE
103  fclose(stdin);
104  #endif
105    return 0;
106}

Related

poj 3630 Phone List (带删除操作的静态trie树模板题)

·555 words·2 mins
poj 3630 题目链接 题意:给出n个字符串,问是否满足所有的字符串都不以其他的字符串为前缀。 思路:字典树,先建树,然后每次查找的之前先删掉自己,找完以后再加回来。 以及这题动态建艹不过。。。学习了一下静态建树的写法。。。第一次写静态的写法。。。可以当做模板用。。。

hdu 1247 Hat’s Words (trie树)

·599 words·2 mins
hdu 1247 题目链接 题意:给出n个字符串的单词表,输出所有的字符串a,满足字符串a是由n中另外两个字符串拼接成的。 思路:字典树。。其实我一开始想出了正解。。。。就是分割一个单词然后分别在trie上查找。。。但是由于题目坑爹得没给单词的长度这个数据范围。。并不是很敢写2333。。。看了下题解发现就是这么做。。。然后写了下1A。。。

hdu 5536 || 2015 长春区域赛 J Chip Factory (带删除操作的trie树)

·905 words·2 mins
hdu 5536 题目链接 题意:给出 n 个数,然后问最大的 (a[i]+a[j])^a[k](i,j,k 互不相同)。 思路:异或和最大很容易想到字典树,但是如何保证 i,j,k 互不相同这里没有想明白。我的想法是加一个标记代表之前的 id,但是我加的标记只有在叶子节点上才有,也就是会出现走到了最后一步才发现这个节点不能走的情况。

hdu 4828 Xor Sum (trie 树模板题,经典应用)

·730 words·2 mins
hdu 4825 题目链接 题意:给定n个数,然后给出m个询问,每组询问一个数x,问n中的数y使得x和y的异或和最大。 思路:字典树。。把每个数转化成二进制,注意补全前导0,使得所有数都有相同的位数。

hdu 1251 统计难题 (trie树模板题)

·475 words·1 min
hdu 1251 题目链接 题意:先给一个单词表,然后给出若干查询,每个查询一个单词,问单词表中以这个单词为前缀的单词的个数。 思路:trie树裸题。第一次写trie树。。感觉要注意的是trie树是一个比较耗费空间的数据结构。。? 以及动态开辟内存记得free…?