航空公司VIP客户查询【PAT】
来源:互联网 发布:宝贝收藏软件 编辑:程序博客网 时间:2024/05/01 00:03
5-06. 航空公司VIP客户查询
不少航空公司都会提供优惠的会员服务,当某顾客飞行里程累积达到一定数量后,可以使用里程积分直接兑换奖励机票或奖励升舱等服务。现给定某航空公司全体会员的飞行记录,要求实现根据身份证号码快速查询会员里程积分的功能。
输入格式说明:
输入首先给出两个正整数N(<=105)和K(<=500)。其中K是最低里程,即为照顾乘坐短程航班的会员,航空公司还会将航程低于K公里的航班也按K公里累积。随后N行,每行给出一条飞行记录。飞行记录的输入格式为:“18位身份证号码(空格)飞行里程”。其中身份证号码由17位数字加最后一位校验码组成,校验码的取值范围为0~9和x共11个符号;飞行里程单位为公里,是(0, 15 000]区间内的整数。然后给出一个正整数M(<=105),随后给出M行查询人的身份证号码。
输出格式说明:
对每个查询人,给出其当前的里程累积值。如果该人不是会员,则输出“No Info”。每个查询结果占一行。
样例输入与输出:
序号输入输出14 500330106199010080419 499110108198403100012 15000120104195510156021 800330106199010080419 1412010419551015602111010819840310001233010619901008041933010619901008041x
800150001000No Info
#include<iostream>#include<stdio.h>#include<time.h>#include<ctype.h>#include<algorithm>#include<string.h>#include<queue>#include<vector>using namespace std;typedef long int lld;//long int#define rot(v) (((v)>>3)|(((v)&7)<<9)) const int MAX=110000;const int MOD=100003;const int INF=1000000000;struct Node{ int a,b; char x; int mile,next;}node[MAX];int head[MOD],E;char buf[22];int chg(char x){ if(x=='x')return 10; return x-'0';}int fun(char s[],int &a,int &b,char &x){ int ret=0,i; int tmp; a=b=0; for(i=0;i<9;i++) { tmp=s[i]-'0'; a=a*10+tmp;//记录没取余数的数值 ret=ret*10+tmp; } ret%=MOD; for(;i<17;i++) { tmp=s[i]-'0'; b=b*10+tmp;//记录后面没取余数的数值 ret=(ret*10+tmp)%MOD; } x=s[i];//记录最后一位 return (ret*100+chg(s[i]))%MOD;//返回取余数的数值}void ins(char s[],int mile){ int a,b; char x; int h=fun(s,a,b,x); int i; //发生冲突时的处理 for(i=head[h];i!=-1;i=node[i].next)//head 全局变量 { if(node[i].x==x&&node[i].a==a&&node[i].b==b) { node[i].mile+=mile; return ; } } node[E].a=a; node[E].b=b; node[E].x=x; node[E].mile=mile; node[E].next=head[h]; head[h]=E++;} int query(char s[]){ int a,b; char x; int h=fun(s,a,b,x); int i; for(i=head[h];i!=-1;i=node[i].next) { if(node[i].x==x&&node[i].a==a&&node[i].b==b)return node[i].mile; } return -1;}void out(int n){ if(n) { out(n/10); putchar('0'+n%10); }}int main(){ int n,m; int k,i; while(scanf("%d%d",&n,&k)!=EOF) { memset(head,-1,sizeof(head)); E=0; int mile=0; while(n--) { scanf("%s%d",buf,&mile); if(mile<k)mile=k; ins(buf,mile); } scanf("%d",&m); getchar(); while(m--) { //scanf("%s",buf); gets(buf); mile=query(buf); if(mile==-1)puts("No Info"); else { out(mile);//cout<<mile;//printf("%d",mile); putchar('\n'); } } } return 0;}
解题报告:题目要求的查询次数可能有105的数量级。时间只有100ms 所以一般顺序查询算法是不能满足要求的。这时候就想到了Hash查询,键值对应结果的查询算法。
即使明确了思路,本题依然存在一下难点:
【1】如何选取适当的Hash函数,构造键值对。
【2】我们要知道任何Hash函数都会存在冲突的问题,即:多组查询结果对应同一个键值,如何解决冲突。
【3】如何在有限的时间限制下找到方法进一步优化程序。
【1】关于函数的选取尝试了几个方法,如果不侦查冲突的话,一般的取余数算法不能满足要求,折叠取余数算法也不行。最后采取的是累加取余数+冲突检测。
【2】要进行冲突检测就必须有足够的数据特征来区别不同的数值。根据本题的特点我们选取前9位的和a和后9位的和b以及最后一位x,还有键值h四个值来标识一个数值。
但是这样存储数据的数据结构就必须要使用结构体。所以我们构建了一个结构体node,包括a,b,x,next,mile。其中next用于存放发生冲突时的下一个数组下标。正常情况下一个键值对应一个数值,这时候的存储过程如下所示:
node[E].next=-1
|
node[0] node[1] node[2] node[3]........node[E]
| |
head[3456] head[h]
发生冲突时存储过程如下所示:
node[E].next=-1 node[E].next=2
| |
node[0] node[1] node[2] node[3]........node[E]
| |
head[3456] head[h]
所以当我们进行查询时,先计算出键值h和标识数值a,b,x,得i=head[h],如果查询node[i]发现(node[i].x==x&&node[i].a==a&&node[i].b==b)的条件不成立,我们知道发生的冲突,接下来就好办了,令i=node[E].next,继续(node[i].x==x&&node[i].a==a&&node[i].b==b)的比对,直到符合条件。
从更一般的角度看其实数据的存储如下图:
有冲突的数据 head[h] 无冲突的数据 head[q]
| |
node[E] node[x]
| |
node[s] (s=node[E].next) NULL(-1=node[x].next)
.......................
【3】效率问题除了一般的时间换空间的思路外,还有一个值得注意的就是输入输出上。
- 航空公司VIP客户查询【PAT】
- PAT DS 506 航空公司VIP客户查询
- 航空公司VIP客户查询
- 航空公司VIP客户查询
- PAT 航空公司VIP客户查询 (哈希 | map) -- 解题报告
- PAT5-06. 航空公司VIP客户查询
- PTA 7-15 航空公司VIP客户查询
- 航空公司VIP客户查询(25 分)
- 5-45 航空公司VIP客户查询 (25分)
- PTA-数据结构 5-45 航空公司VIP客户查询 (25分)
- 航空公司VIP客户查询(25 分)(Hash)
- 《数据结构学习与实验指导》5-6:航空公司VIP客户查询
- 7-15(查找) 航空公司VIP客户查询(25 分)
- PTA 7-15(查找) 航空公司VIP客户查询(25 分) 25分代码 哈希方法
- 航空公司客户价值分析
- 实战:航空公司客户价值分析
- 3航空公司客户价值分析
- 利用聚类分析航空公司客户价值
- 结构体
- 数据库设计三大范式
- 单片机课后习题
- 深入理解Java内存模型(二)——重排序
- html5 canvas旋转
- 航空公司VIP客户查询【PAT】
- 详细探究Spark的shuffle实现
- jquery获取Url和JS获取Url的参数值
- php中的date函数中时区问题
- JDBC连接各种数据库方法
- android 显示related
- Virtualbox主机和虚拟机之间文件夹共享及双向拷贝(Windows<->Windows, Windows<->Linux)
- Linux CVE-2009-0029 漏洞解析
- poj 3659