hdu - 3724 - Encoded Barcodes(Trip)

题意:有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;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值