陈老师的多校联合 20140808 E题

http://vjudge.net/contest/view.action?cid=51407#problem/E

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(1N10000, 1M2000), 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 < K30) 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.


Explanation for the sample:

There 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.

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
题目大意:给定n个字符串,还有m组数据,这m组中,每一组有x个字符,1~x每行有8个数代表0或者1,然后组成一个二进制数,而后正好对应一个字母的ASCII码,x个字符组成一个字符串,判读m个字符串是以上n个字符串中多少个的前缀,取和。

解题思路:好像是模拟,值得一提的是每组的8个数中不是正好的二倍关系,注意处理(无论怎样大的肯定还是小的1.5倍以上,我就是利用这一点取得值)。

还有:这个题数据好像水了,我的代码本觉得会超时,没想到竟然过了==

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=10005;
double num[35][8];
char sum[2200][35];
char a[N][35];
int n,m;
int pow(int j)
{
    int sum=1;
    for(int i=0;i<j;i++)
        sum*=2;
    return sum;
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        getchar();
        for(int i=0;i<n;i++)
        {
            scanf("%s",a[i]);
            getchar();
        }
        for(int k=0;k<m;k++)
        {
            int x;
            scanf("%d",&x);
            for(int i=0;i<x;i++)
            {
                double minn=99999999.0;
                for(int j=0;j<8;j++)
                {
                    scanf("%lf",&num[i][j]);
                    minn=min(num[i][j],minn);
                }
                for(int j=0;j<8;j++)
                {
                    if(num[i][j]/minn>1.5)
                        num[i][j]=1.0;
                    else
                        num[i][j]=0.0;
                }
               /**
                  for(int l=0;l<8;l++)
                     printf("%lf ",num[i][l]);
                     **/
                sum[k][i]=0;
                for(int j=0;j<8;j++)
                     sum[k][i]+=(int)num[i][j]*pow(7-j);
            }
            sum[k][x]=0;
           // printf("%s\n",sum);
        }

        /**
        for(int i=0;i<m;i++)
            printf("%s\n",sum[i]);
        **/

        int count=0;
        for(int i=0;i<m;i++)
        {
            int len=strlen(sum[i]);
            for(int j=0;j<n;j++)
            {
                int k;
                for(k=0;k<len;k++)
                   if(a[j][k]!=sum[i][k])
                      break;
                if(k==len)
                   count++;
            }
        }
        printf("%d\n",count);
    }
    return 0;
}


你可能感兴趣的:(陈老师的多校联合 20140808 E题)