找球号(二)
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
5
-
描述
-
在某一国度里流行着一种游戏。游戏规则为:现有一堆球中,每个球上都有一个整数编号i(0<=i<=100000000),编号可重复,还有一个空箱子,现在有两种动作:一种是"ADD",表示向空箱子里放m(0<m<=100)个球,另一种是"QUERY”,表示说出M(0<M<=100)个随机整数ki(0<=ki<=100000100),分别判断编号为ki 的球是否在这个空箱子中(存在为"YES",否则为"NO"),先答出者为胜。现在有一个人想玩玩这个游戏,但他又很懒。他希望你能帮助他取得胜利。
-
输入
-
第一行有一个整数n(0<n<=10000);
随后有n行;
每行可能出现如下的任意一种形式:
第一种:
一个字符串"ADD",接着是一个整数m,随后有m个i;
第二种:
一个字符串"QUERY”,接着是一个整数M,随后有M个ki;
输出
- 输出每次询问的结果"YES"或"NO". 样例输入
-
2 ADD 5 34 343 54 6 2 QUERY 4 34 54 33 66
样例输出
-
YES YES NO NO
来源
利用Hash数组判重:
构建链式Hash有两种实现方法一种是直接使用链表实现,另一种是利用数组模拟链表
在这里我使用的利用数组模拟链表实现,构建方法如下:
1 . 数组实现需要三个数组 key[],Head[],Next[],Key[]用来存储数据,Head[i] i 表示键值,存储键值为i 的数从Next[]中开始的下表,Next[]存储下一个数的下标,设置cont变量记录插入数目的个数
2.Head[] 初始化为-1,Next[],Key[],初始化为0
3.执行Add(num)操作:
1).h=Hash(num); //计算出num对应的Hash值
2).将num插入Key[],即Key[cont]=num;
3).需要先让Next[cont],记录此时Head[h]的值,即Next[cont]=Head[h]
4).将此时的cont值接到在Head[]中对应的位置,即Head[h]=cont
5).cont++ 注意3),4),的顺序,不能搞反
4.执行Find(num)操作:
1).求出num对应Hash值
2).从Head[]中找出开始的位置,直到值为-1,结束
即for(int i=Head[h];i!=-1;i=Next[i])
第二步就是遍历所有Hash值为h的数字
本题代码:
#include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #define MAX 1000010 #define MAXSIZE 100024 int key[MAX],head[MAX],next[MAX]; int top; void Add(int number){ int h=number%MAXSIZE; key[top]=number; next[top]=head[h]; head[h]=top; top++; } int Find(int number){ int h=number%MAXSIZE; for(int i=head[h];i!=-1;i=next[i]){ if(key[i]==number) return 1; } return 0; } int main(){ int n; scanf("%d",&n); memset(head,-1,sizeof(head)); memset(key,0,sizeof(key)); while(n--){ char str[10]; scanf("%s",str); if(str[0]=='A'){ int m; scanf("%d",&m); for(int i=0;i<m;i++){ int number; scanf("%d",&number); Add(number); } } else{ int M; scanf("%d",&M); for(int i=0;i<M;i++){ int num; scanf("%d",&num); if(Find(num)) printf("YES\n"); else printf("NO\n"); } } } }
-
第一行有一个整数n(0<n<=10000);