题意:有N个产品,名称由小写字母组成,有M个询问,每个询问先来一个K,再输入K个条形码,每个条形码代表1个小写字母,这K个条形码连成连续的K个字母作为前缀,统计这个前缀是多少个产品名的前缀(重复的算多次),输出M个询问的统计个数和(1 <= N <= 10000, 1 <= M <= 2000, 0 < K <= 30, 产品名长度 <= 30)。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3724
——>>组织好Trip后,把条形码转换为小写字母(大于平均值的为1,否则为0,计算ASCII码),连成串,在Trip查找,求和。
#include <cstdio> #include <cstring> using namespace std; const int maxn = 30 + 5; const int maxb = 8 + 5; int N, M, K, bit[maxb]; double bar[maxb]; char qus[maxn]; struct node{ int cnt; node *next[26]; node(){ cnt = 0; memset(next, 0, sizeof(next)); } }; struct Trip{ node *root; int ret; Trip(){ root = new node; ret = 0; } int idx(char c){ return c - 'a'; } void insert(char *s){ int len = strlen(s), i; node *t = root; for(i = 0; i < len; i++){ int c = idx(s[i]); if(!t->next[c]) t->next[c] = new node; t->next[c]->cnt++; t = t->next[c]; } } void solve(){ node *t = root; int len = strlen(qus), i; for(i = 0; i < len; i++){ int c = idx(qus[i]); if(!t->next[c]) break; t = t->next[c]; } if(i == len) ret += t->cnt; } void print(){ printf("%d ", ret); } }; int main() { char product[maxn]; int i, j, k; while(scanf("%d%d", &N, &M) == 2){ Trip trip; for(i = 0; i < N; i++) { scanf("%s", product); trip.insert(product); } for(i = 0; i < M; i++){ int cnt = 0; scanf("%d", &K); for(j = 0; j < K; j++){ double sum = 0; for(k = 0; k < 8; k++){ scanf("%lf", &bar[k]); sum += bar[k]; } sum /= 8; int ASCII = 0; for(k = 0; k < 8; k++) if(bar[k] > sum) ASCII += (1 << (7-k)); qus[cnt++] = (char)ASCII; } qus[cnt] = ' '; trip.solve(); } trip.print(); } return 0; }