codevs 1230 元素查找(hash)

题目描述 Description
给出n个正整数,然后有m个询问,每个询问一个整数,询问该整数是否在n个正整数中出现过。

输入描述 Input Description
第一行两个整数 n 和m。
第二行n个正整数(1<=n<= 100000)
第三行m个整数(1<=m<=100000)

输出描述 Output Description
一共m行,若出现则输出YES,否则输出NO

样例输入 Sample Input
4 2
2 1 3 4
1 9

样例输出 Sample Output
YES
NO

数据范围及提示 Data Size & Hint
所有数据都不超过10^8

题解:这道题可以用hash表来做,对于每个数我们mod一下10000作为他的hash值,如果存在冲突就用链表存一下。查找的时候直接根据要查找数的hash值就能直接找到这个数有没有出现过。
PS:这道题我刚开始mod10007然后WA了,我改成mod10000就AC了,不是说要尽量mod素数吗QAQ

代码如下

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int MAXN=100000010;
const int mod=10000;
int tot,head[MAXN/mod];
struct links
{
    int f,t;
}es[MAXN/10];
int hash(int x)
{
    return x%mod;//以他mod10000作为hash值 
}
void add(int x,int y)
{
    es[++tot]=(links){y,head[x]};//按照他的hash值存入链表 
    head[x]=tot;
}
bool ask(int x,int y)
{
    for(int i=head[x];i;i=es[i].t)
        if(es[i].f==y) return true;//在链表中找到这个数 
    return false;
}
int main()
{
    int n,m,x;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        add(hash(x),x);//按照他的hash值加入链表 
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&x);
        if(ask(hash(x),x)) printf("YES\n");//通过他的hash值能够找到这个数,说明出现过 
        else printf("NO\n");
    }
    return 0;
}
发布了81 篇原创文章 · 获赞 2 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/Loi_YZS/article/details/53095511