#哈希#SSL 1125 集合

本文介绍了三种高效算法:使用C++ map实现的时间复杂度较高的方法、快排加二分搜索的中等时间复杂度方法及哈希表实现的较低时间复杂度方法,用于判断两个集合之间的相等、子集、真子集或无交集关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

求两个集合的关系


分析:

c++ map大法 快排+二分 哈希 比较时间
首先如果答案和两个数组的数据个数相等为同一个集合
如果和第一个相等 B包含与A 和第二个相等 A包含于B
有答案说明交集不为空 否则有交集confused


map(622ms)代码

#include <cstdio>
#include <cctype>
#include <map>
using namespace std;
int n1,n2,ans; map<int,bool>uk;
inline int ip(){
	char c=getchar(); int ans=0;
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=ans*10+c-48,c=getchar();
    return ans;
}
int main(){
    n1=ip(); for (int i=1;i<=n1;i++) uk[ip()]=1; //标记布尔数组
    n2=ip(); for (int i=1;i<=n2;i++) ans+=uk[ip()];//判断
	if (ans==n2&&ans==n1) puts("A equals B");
	else if (ans==n2&&ans<n1) puts("B is a proper subset of A");
	else if (ans==n1) puts("A is a proper subset of B");
	else if (!ans) puts("A and B are disjoint"); else puts("I'm confused!");
	return 0;
}

快排+二分(215ms) 代码

#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
int a[100001],b[100001],n1,n2,ans;
inline int ip(){
	char c=getchar(); int ans=0;
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=ans*10+c-48,c=getchar();
    return ans;
}
void pu(int &n,int *c){n=ip(); for (int i=1;i<=n;i++) c[i]=ip();}
int main(){
	pu(n1,a); pu(n2,b);
	stable_sort(a+1,a+1+n1);//对前一个数组快排
	for (int i=1;i<=n2;i++){
		int l=1,r=n1,mid;
		while (l<=r){//二分
			mid=(l+r)>>1;
			if (a[mid]==b[i]) break;
			else if (a[mid]>b[i]) r=mid-1; else l=mid+1;
		}
		if (a[mid]==b[i]) ans++;//查找到答案增加
	}
	if (ans==n2&&ans==n1) puts("A equals B");
	else if (ans==n2&&ans<n1) puts("B is a proper subset of A");
	else if (ans==n1) puts("A is a proper subset of B");
	else if (!ans) puts("A and B are disjoint"); else puts("I'm confused!");
	return 0;
}

哈希(154ms)代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#define p 149993
using namespace std;
int a[p+1],n1,n2,ans;
inline int ip(){
	char c=getchar(); int ans=0;
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=ans*10+c-48,c=getchar();
    return ans;
}
int locate(int x){
    int orig=x%p,i=0;
    while (i<p&&a[(orig+i)%p]!=x&&a[(orig+i)%p]) i++;//往后寻找
    return (orig+i)%p;
}
void insert(int x){a[locate(x)]=x;}
bool find(int x){return a[locate(x)]==x;}
int main(){
    n1=ip(); for (int i=1;i<=n1;i++) insert(ip());//插入
    n2=ip(); for (int i=1;i<=n2;i++) if (find(ip())) ans++;//寻找
	if (ans==n2&&ans==n1) puts("A equals B");
	else if (ans==n2&&ans<n1) puts("B is a proper subset of A");
	else if (ans==n1) puts("A is a proper subset of B");
	else if (!ans) puts("A and B are disjoint"); else puts("I'm confused!");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值