【HASH】有关哈希表的练习和研究

codevs1553 互斥的数 
题目描述   Description

有这样的一个集合,集合中的元素个数由给定的N决定,集合的元素为N个不同的正整数,一旦集合中的两个数x,y满足y = P*x,那么就认为x,y这两个数是互斥的,现在想知道给定的一个集合的最大子集满足两两之间不互斥。

输入描述 Input Description

输入有多组数据,每组第一行给定两个数NP1<=N<=10^5, 1<=P<=10^9)。接下来一行包含N个不同正整数ai1<=ai<=10^9)。

输出描述 Output Description

输出一行表示最大的满足要求的子集的元素个数。

样例输入 Sample Input

4 2

1 2 3 4

样例输出 Sample Output


 Codevs1230 元素查找
 题目描述 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
对于这两个题,由于难度比较低,所以使用最简单的哈希函数取模运算就好了
然后用开放域法将其存储。
当然我们有更加高端的存储方法和解决冲突的方法,不过由于个人太弱而/不会使用指针,完全不会用QAQ
其实个人更加偏向使用多个HASH函数解决冲突,但是还不太会用orz
史上第一次HASH的练习 
愉快的贴代码时刻www
1553

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int n,p,a[100001],ans;
int pd[1000008];
void hash(int x)
{
int t=x;
while (t%p==0)
t/=p;
t=t%1000007;
while(1)
{
if(!pd[t])
{
pd[t]=x;
ans++;
return;
}
else
{
if (x%pd[t]==0)
{
if (x/pd[t]!=p)
{
ans++;
pd[t]=x;
}
return;
}
else
{
t++;
if(t==1000008) t=0;
}
}
}
}
main()
{
scanf("%d%d",&n,&p);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
hash(a[i]);//哈希函数(最朴素版本)
printf("%d",ans);
} 


1230 元素查找//P.S.本题除了hash其实有更快更简单的解法。比如直接价加个布尔数组暴力什么的事实证明hash效率比那样要低很多

#include<cstdio>  

#include<cstring>  

using namespace std;  

int n,m,hs[100007];  

bool pd[100007];  

int hash(int x)

{  

    int t=x%100007;  

    while(pd[t]&&hs[t]!=x)

 t=(t+1)%100007;  

    pd[t]=1;  

    return t;  

}  

int main(){  

    memset(pd,0,sizeof(pd));  

    scanf("%d %d",&n,&m);  

    for(int i=1;i<=n;i++)

{  

         int t;

scanf("%d",&t);  

         hs[hash(t)]=t;  

    }  

    for(int i=1;i<=m;i++)

{  

        int t;

scanf("%d",&t);  

        if(hs[hash(t)]==t) printf("YES\n");  

        else printf("NO\n");  

    }  

    return 0;  

} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值