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 }