HDU 3724 字典树

Encoded Barcodes

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1644    Accepted Submission(s): 569

Problem Description

All the big malls need a powerful system for the products retrieval. Now you are employed design a sub-system: reading the barcodes and return the matching products.

A barcode is an optical machine-readable representation of data, which shows certain data on certain products. A barcode consists of a series of bars with different widths. In our system, the barcodes have been scanned and the widths have been recorded. Every consecutive eight bars are considered as representing the ASCII code of a character, each bar for each bit. Ideally, there should be only two kinds of widths in the eight bars, and the width of the wider bar is twice of the narrower. The wider bar indicates 1, while the narrower indicates 0. However, due to the inaccuracy of printing and scanning, there will be an error of at most 5%. That is, if the pretended exact width is x, you may get a value in the range [0.95x, 1.05x].

For example, the width sequence "10.0 20.0 10.0 10.0 10.0 10.0 10.0 20.0" is a valid barcode of our system, and it means (01000001)2, which is (65)10 and the corresponding character is "A". Note that "10.5 20.1 10.1 10.2 9.9 9.7 10.0 19.9" is also a valid barcode representing the same letter.

You are given the names of all the products and many queries. Every name contains lower-case letters only, and the length is no more than 30. The queries are represented as barcodes. For each query, you should decode it to a string S, and report the amount of products whose prefix is S. For the output may be very large, you only need to output the sum of all the queries for each case.

Input

There are several test cases in the input. The first line of each case contains two integers N and M (1 <= N <= 10000, 1 <= M <= 2000), indicating the number of products and queries. Then N lines follow, indicating the names of the products. Note that the names may be duplicated. Then M query blocks follow. The first line of each query block is an integer K (0 < K <= 30) indicating the length of the query, then K lines follow, each line contains 8 positive float numbers, indicating the barcode for each character.

You can assume that the barcodes are always valid, and always represent lower-case letters.

Output

Output one line for each test case, indicating the sum of all the query results as described above.

Sample Input

4 3

apple

apple

avatar

book

1

1 2 2 1 1 1 1 2

2

1 2 2 1 1 1 1 2

10.1 20.1 19.9 20.0 10.2 9.8 9.9 10.0

1

1 2 2 1 1 1 2 2

Sample Output

5

题目意思:
直接解释样例,4 3表示4个固定的字符,3表示3次查询。  下面4行为输入的固定的字符串,每次查询第一个为前缀字母的个数,每个前缀字母由二进制构成。

比如

1

1 2 2 1 1 1 1 2

即前缀字母为1个,1下面8个数字为二进制,即若a是b的二倍(输入的数据有一定的误差),那么a为1,b为0。这组样例中二进制即为 01100001 即为字符‘a‘,这个字符是3个固定字符串的前缀  ans+=3.

2

1 2 2 1 1 1 1 2               即为字符‘a’

10.1 20.1 19.9 20.0 10.2 9.8 9.9 10.0    即为字符 ‘p‘

那么字符串为"ap"为2个固定字符串的前缀,ans+=3

1

1 2 2 1 1 1 2 2   字符‘a‘  ans+=0

output  5.

思路:
先把固定字符串插入字典树中,经过的每个结点记录+1,然后把查询即可。

代码有点渣。。。:

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <iostream>
  5 #include <vector>
  6 #include <queue>
  7 #include <cmath>
  8 using namespace std;
  9
 10 struct node{
 11     int p;
 12     struct node *next[26];
 13     node(){
 14         p=0;memset(next,0,sizeof(next));
 15     }
 16 }root;
 17
 18 int n, m;
 19
 20 void insert(char *s){
 21     int k=0;
 22     node *p=&root;
 23     while(s[k]){
 24         if(!p->next[s[k]-‘a‘]){
 25             p->next[s[k]-‘a‘]=new node;
 26             p=p->next[s[k]-‘a‘];p->p=1;
 27         }
 28         else {
 29             p=p->next[s[k]-‘a‘];p->p++;
 30         }
 31         k++;
 32     }
 33 }
 34
 35 int find(char *s){
 36     node *p=&root;
 37     int k=0;
 38     while(s[k]){
 39         if(!p->next[s[k]-‘a‘]) return 0;
 40         else p=p->next[s[k]-‘a‘];
 41         k++;
 42     }
 43     return p->p;
 44 }
 45
 46
 47 void Delete(node *p)
 48 {
 49     for(int i=0;i<26;i++)
 50         if(p->next[i]) Delete(p->next[i]);
 51         delete(p);
 52 }
 53 main()
 54 {
 55     int i, j, k, l;
 56     int num, ans;
 57     double a[8];
 58     double b[8];
 59     char s[1000];
 60     while(scanf("%d %d",&n,&m)==2){
 61         root=*new node;
 62         while(n--){
 63             scanf("%s",s);
 64             insert(s);
 65         }
 66         int f, w;
 67         ans=0;
 68         while(m--){
 69             scanf("%d",&k);l=0;
 70             while(k--){
 71                 double maxh=0;
 72                 for(i=0;i<8;i++){
 73                     scanf("%lf",&a[i]);maxh+=a[i];
 74                 }
 75                 f=0;
 76                 double q;
 77                 maxh/=8;
 78                 for(i=0;i<8;i++){
 79                     for(j=i+1;j<8;j++){
 80                         int c1=round(a[i]/a[j]);
 81                         if(c1==2){
 82                             f=1;q=a[j];break;
 83                         }
 84                         else if(b[i]*2==0){
 85                             f=1;q=a[i];break;
 86                         }
 87                     }
 88                     if(f) break;
 89                 }
 90
 91                 num=0;
 92                 if(f)
 93                 for(i=0;i<8;i++){
 94                     int c=round(a[i]/q);
 95                     if(c==1) num*=2;
 96                     else num=num*2+1;
 97                 }
 98                 char c=(char)num;
 99             //    printf("%d %d\n",‘a‘,‘Z‘);
100                 if(c>=‘a‘&&c<=‘z‘)
101                 s[l++]=c;
102             }
103             s[l]=‘\0‘;
104         //    printf("%s\n\n",s);
105             ans+=find(s);
106         }
107         printf("%d\n",ans);
108         delete(&root);
109     }
110 }
时间: 2024-08-11 09:38:33

HDU 3724 字典树的相关文章

HDU 1800 字典树

Flying to the Mars Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10065    Accepted Submission(s): 3270 Problem Description In the year 8888, the Earth is ruled by the PPF Empire . As the popul

hdu 1075 字典树

// hdu 1075 字典树 // // 题目大意: // // 给你一个字典,即有两个字符串,一个是英文,一个是火星文,然后 // 输入一段火星文,要你翻译成英文. // // 解题思路: // // 字典树,查字典嘛,有就输出查到的,没有原样输出.将火星文插入到 // 字典树中,然后在字典输中查找.找到了,输出对应的英文,否则,原样输 // 出. // // 感悟: // // 题目确实很简单,但是,没告诉数据范围啊,导致我一直RE,原来单词 // 可能对应很长的英文啊,找人家ac的开数组

HDU 1251 字典树入门

统计难题 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others)Total Submission(s): 17177    Accepted Submission(s): 7410 Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前

HDU 5384 字典树、AC自动机

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5384 用字典树.AC自动机两种做法都可以做 1 #include<stdio.h> 2 #include<string.h> 3 #include<string> 4 #include<iostream> 5 using namespace std; 6 struct node{ 7 int cnt; 8 node *next[26]; 9 node(){ 10 c

HDU 5687 字典树插入查找删除

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5687 2016百度之星资格赛C题,直接套用字典树,顺便巩固了一下自己对字典树的理解 1 #include<stdio.h> 2 #include<string.h> 3 struct node{ 4 int next[27]; 5 int cnt; 6 void init(){ 7 cnt = 0;//计数 8 memset(next,-1,sizeof(next)); 9 } 10 };

hdu 5269 字典树

题目链接:hdu 5269 ZYB loves Xor I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 184    Accepted Submission(s): 101 Problem Description Memphis loves xor very musch.Now he gets an array A.The lengt

hdu 2112(字典树+最短路)

HDU Today Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 23388    Accepted Submission(s): 5614 Problem Description 经过锦囊相助,海东集团终于度过了危机,从此,HDU的发展就一直顺风顺水,到了2050年,集团已经相当规模了,据说进入了钱江肉丝经济开发区500强.这时候,

Flying to the Mars HDU - 1800(字典树)

Flying to the Mars HDU - 1800 题目链接:https://vjudge.net/problem/HDU-1800 题目:在8888年,地球由PPF帝国统治.随着人口的增长,PPF需要为新生儿寻找更多的土地.最后,PPF决定攻击统治火星的Kscinow.问题来了!士兵怎么能到达火星? PPF召集他的士兵并询问他们的建议. “匆匆......”一名士兵回答. “闭嘴 !我是否必须提醒你,从这里到火星没有任何道路!“PPF回复道. “飞!”另一个答案. PPF笑道:“聪明的

Chip Factory HDU - 5536 字典树(删除节点|增加节点)

题意: t组样例,对于每一组样例第一行输入一个n,下面在输入n个数 你需要从这n个数里面找出来三个数(设为x,y,z),找出来(x+y)^z(同样也可以(y+z)^1)的最大值 (“^”代表异或操作,即“相同为0,不同为1”) 题解: 这一道题和Xor Sum HDU - 4825很相似 因为异或运算的特性,我们最后要求最大值,那我们就对这n个数的二进制形式建一颗字典树.然后就暴力枚举是哪两个数相加,然后在字典树中把这两个数删掉.然后在处理完的字典树中查找那个能使结果尽可能大的第三个数(至于怎么