题意:有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\n", 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] = '\0';trip.solve();}trip.print();}return 0;
}