連結:
http://acm.hdu.edu.cn/showproblem.php?pid=3724
題目:
Encoded Barcodes
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1022 Accepted Submission(s): 337
Problem DescriptionAll 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.
InputThere 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.
OutputOutput one line for each test case, indicating the sum of all the query results as described above.
Sample Input
4 3appleappleavatarbook11 2 2 1 1 1 1 221 2 2 1 1 1 1 210.1 20.1 19.9 20.0 10.2 9.8 9.9 10.011 2 2 1 1 1 2 2
Sample Output
5HintThere 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.
題目大意:
先給出所有產品名稱, 然後輸入查詢詞, 統計以這個查詢詞為首碼的產品個數。查詢詞的輸入比較特殊,是輸入條碼的每一條的寬度。寬度共有兩種類型,一種比較寬,一種是窄的, 寬的是窄的長度的兩倍。 注意, 如果寬的那個是1, 那麼窄的是0。然後把這個條碼轉換成位元,寬的位元對應1,窄的對應0.然後會得到一個ASCII碼, 是字母'a' ~'z'的範圍。
分析與總結:直接統計首碼,字典樹的一個典型應用。 這題的關鍵是處理條碼。可以把所有寬度求和, 再求平均長度,大於平均長度的是寬的那條,小於平均長度是窄的那條。
代碼:
#include<iostream>#include<cstdio> #include<cstring>using namespace std;const int KIND = 26;const int MAXN = 500000;int cnt_node;double width[8];struct node{ int cnt; node* next[KIND]; void init(){ cnt = 0; memset(next, 0, sizeof(next)); }}Heap[MAXN];inline node* new_node(){ Heap[cnt_node].init(); return &Heap[cnt_node++];}void insert(node* root, char *str){ for(char *p=str; *p; ++p){ int ch=*p-'a'; if(root->next[ch]==NULL) root->next[ch] = new_node(); root = root->next[ch]; ++root->cnt; }}int count(node* root, char *str){ for(char *p=str; *p; ++p){ int ch=*p-'a'; if(root->next[ch]==NULL) return 0; root=root->next[ch]; } return root->cnt;}int main(){ int n,m,q; char str[40]; while(~scanf("%d%d",&n,&m)){ // Trie tree init cnt_node=0; node *root = new_node(); // word input for(int i=0; i<n; ++i){ scanf("%s",str); insert(root, str); } int ans=0; while(m--){ scanf("%d",&q); memset(str, 0, sizeof(str)); int p=0; for(int k=0; k<q; ++k){ double x; double sum=0; for(int i=0; i<8; ++i){ scanf("%lf",&width[i]); sum += width[i]; } sum /= 8.0; int ch=0; for(int i=7, d=1; i>=0; --i){ if(width[i] > sum){ ch |= d; } d <<= 1; } if(ch>='a' && ch<='z') str[p++] = (char)ch; } ans += count(root, str); } printf("%d\n",ans); } return 0;}
—— 生命的意義,在於賦予它意義士。
原創 http://blog.csdn.net/shuangde800 , By
D_Double (轉載請標明)