HDU 3724 Encoded Barcodes(trie树)

Encoded Barcodes

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


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
Hint
There is only one test case. The first query is "a", and the answer is 3. The second query is "ap", and the answer is 2. The third query is "c", and the answer is 0. So the total sum is 3+2+0 = 5.
 

Source
 

Recommend
zhouzeyong
 


这个题目是2010天津赛区现场赛的题目,题目比较容易,但是我wa了两次!

这次wa的原因不是程序问题,是run time error  原因是对于语言的理解上面,我定义的结构提是有构造函数的,但是我在申请的时候用的是malloc
那么这个函数是C语言里面申请内存块的一个函数,申请的就是size大小的一个内存块,不会认为这段内存块是分配给某个对象或者什么的,所以
不会调用构造函数,那么就完了,肯定run time error了
这个题目思路比较简单,就是trie树,在插入的过程中将路途中经过的所有节点的num+1,最后查询就OK了
还有那个条形码,怎样判断是0还是1,我是这样的,找出最大的,和最小的,取平均,只要比平均大的就是1
否则是0,这样就OK了,然后查询结果加起来就好了!

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int n,m;
struct trie
{
int num;
trie *next[26];
trie()
{
num=0;
memset(next,0,sizeof(next));
}
}re_root;
int insert_trie(trie *root,char *name)
{
if(name[0]==0)
{
root->num++;
return 0;
}
root->num++;
int temp=int(name[0]-'a');
if(root->next[temp]!=NULL)
insert_trie(root->next[temp],name+1);
else
{
root->next[temp]=new trie;
insert_trie(root->next[temp],name+1);
}
return 0;
}
int query(trie *root,char *name)
{
if(name[0]==0)
return root->num;
int temp=name[0]-'a';
if(root->next[temp]!=NULL)
return query(root->next[temp],name+1);
else
return 0;
}
int main()
{
int i,j,k,r;
int ans;
char str[10000];
char pattern[10000];
double code[10];
double Max,Min,Avg;
int two;
while(scanf("%d%d",&n,&m)!=EOF)
{
re_root.num=0;
memset(re_root.next,0,sizeof(re_root.next));
ans=0;
for(i=0;i<n;i++)
{
scanf("%s",str);
insert_trie(&re_root,str);
}
for(i=0;i<m;i++)
{
scanf("%d",&k);
for(j=0;j<k;j++)
{
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&code[0],&code[1],&code[2],&code[3],&code[4],&code[5],&code[6],&code[7]);
Max=code[0];
Min=code[0];
for(r=1;r<8;r++)
{
if(code[r] > Max)
Max=code[r];
if(code[r] < Min)
Min=code[r];
}
two=0;
Avg=(Max+Min)/2;
for(r=0;r<8;r++)
if(code[r] > Avg)
two+=(1<<(7-r));
//printf("two:%d %lf\n",two,Avg);
pattern[j]=two;
}
pattern[k]=0;
ans+=query(&re_root,pattern);
}
printf("%d\n",ans);
}
return 0;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值