SSL P1125 集合(normal)

题目:

点击查看题目

题意:

给出两个集合,让我们求出他们之间的关系(哈希算法模版体)

分析:

当读完题目后,倘若不加思考,定会十分头大。而当小编细心留意后,猛然发现,因为集合全都是数字,那么我们可以通过哈希算法入手,进行判重。最后在根据我们统计出来他们重复了多少个数字,从而分类输出。当然我们同样可以采用二分+快速排序来做,且在此题上,用该种做法时间效率更高。
在这里,小编会将两种代码一起奉上!

代码:(哈希版)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int a,h[149993],t=0;
int locate(int x)//哈希算法中的定位(为了方便记忆,可将其记为“老菜苔”)
{
    int wz=x%149993;//这里小编选用149993这个素数作为哈希素数(哈希素数用来看我们当前这个数应该存放在哪里,不要过大,也不要过小。需择中选择)
    while(h[wz]!=0&&h[wz]!=x)
      wz++,wz%=149993;//定位,直到我们找到第一个与自己相同的数或空位
    return wz;
}
void in(int x)
{
    h[locate(x)]=x; //将这个数插入哈希数组中
    return;
}
bool pd(int x)
{
    if(h[locate(x)]==x) return 1;//判断这个数是否在哈希数组中(判重)
    return 0;
}
int main()
{
    int n=0,m=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) 
    {
        scanf("%d",&a);
        in(a);//将a集合所有数存入哈希表中
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++) 
    {
        scanf("%d",&a);//输入b集合
        if(pd(a)==1) t++;//看这些数有没有在哈希表中,有则意味这重复了,所以将统计变量+1
    }
    //分情况输出
    if(t==n&&t==m) puts("A equals B");
    else if(t==n&&t<m) puts("A is a proper subset of B");
    else if(t==m&&t<n) puts("B is a proper subset of A");
    else if(t==0) puts("A and B are disjoint");
    else puts("I'm confused!");
    return 0;
}

代码:(二分+快速排序)

//相对于哈希,这种方法更为简单
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define LL long long
using namespace std;
inline LL read()
{
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9') {if(s=='-') f=-1;s=getchar();}
    while(s>='0'&&s<='9') {d=d*10+s-'0';s=getchar();}
    return d*f;
}
int x[100005];
int a,n,t;
void ef()//二分查找,求b集合的数在a集合中是否存在
{
    int l,r,mid;
    l=1;r=n;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(x[mid]==a) {t++;return;}
        if(x[mid]>a) r=mid-1;
        else if(x[mid]<a) l=mid+1;
    }
}
int main()
{
    int m;
    n=read();
    for(int i=1;i<=n;i++) x[i]=read();
    sort(x+1,x+n+1);//cpp快速排序
    m=read();
    for(int i=1;i<=m;i++)
    {
        a=read();
        ef();
    }
    //分情况输出
    if(t==n&&t==m) puts("A equals B");
    else if(t==n&&t<m) puts("A is a proper subset of B");
    else if(t==m&&t<n) puts("B is a proper subset of A");
    else if(t==0) puts("A and B are disjoint");
    else puts("I'm confused!");
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值