POJ 2153

来源:互联网 发布:java替换双引号 编辑:程序博客网 时间:2024/05/20 04:48


    题目链接:http://poj.org/problem?id=2153

     题意:一个班上有n个学生(一定包含学生Li Ming),接下来有m次考试,每次考试过后,每个学生都有


一个分数,问每轮考试过后,Li Ming的总分(也就是之前每次考试所得的分数的总和)排在第几名.


    数据范围:1<=n<=10000,1<=m<=50,每次考试的分数是不大于100的正整数.


     解题思路:


            用于m值太小,所以每个学生的总分必然不超过5000,所以查询排名的时候可用线段树


进行优化,由于每次读入一个名字,需要找寻它前面考试分数的总和,普通的遍历O(n*len)


(len为学生名字的平均长度)时间复杂度太高,所以这里我用到的是BKDHash函数实现的将字符串


映射成一个整数,然后进行查找,就能比较高效了(需要解决冲突).


关于字符串hash函数,这位大牛总结的挺好的,感兴趣的可以参考下.


https://www.byvoid.com/blog/string-hash-compare/



hash代码:

#include<stdio.h>#include<string.h>#include<vector>#define M 10007#define MAX_N 5100using namespace std;//cnt数组用来记数int score[M],cnt[MAX_N];vector<int> vec[M];char name[M][40];unsigned int BKDHash(char *str){    unsigned int seed = 131,hash=0;    while(*str)        hash = hash * seed + (*str++);    return hash & M ;}int main(){    int n,m,res_index;    scanf("%d",&n);    getchar();    for(int i=0;i<n;++i)    {        gets(name[i]);        if(strcmp(name[i],"Li Ming")==0)            res_index = i ;        vec[BKDHash(name[i])].push_back(i);    }    scanf("%d",&m);    getchar();    char tmp[100];    for(int I=0;I<m;++I)    {        for(int i=0;i<n;++i)        {            int t_score;            gets(tmp);            sscanf(tmp,"%d",&t_score);            int j = 0 ;            for(int len=strlen(tmp);j < len;)            {                if((tmp[j] >= '0' && tmp[j] <= '9') || tmp[j]==' ' || tmp[j]=='\t')                    ++j;                else                    break;            }            int index1 = BKDHash(tmp+j),index2;            for(int k=0;k < vec[index1].size();++k)            {                if(strcmp(name[vec[index1][k]],tmp+j) == 0)                {                    index2 = vec[index1][k];                    break;                }            }            //删掉以前的分数            if(I)                --cnt[score[index2]];            //插入现有的分数            ++cnt[score[index2]+=t_score];        }        int res = 1;        for(int i=score[res_index]+1;i <= MAX_N;++i)            if(cnt[i])                res +=cnt[i];        printf("%d\n",res);    }                  return 0;}


0 0
原创粉丝点击