SSL-ZYC 1125 集合
题目大意:
判断两个数字串的关系。
思路:
这道题有两种方法:
(1)快排+二分
(2)哈希
如果用快排+二分,那我们就要把第一个数字串排序,然后第二个数字串每当输入一个数字就用二分查看这个数字是否在第一个数字串中出现。
如果用哈希,那就设置一个质数k=149993(WYC找出来的一个可以AC的好质数),然后每输入第二个数字串的一个数字时就用哈希查找。
如果在第一个数字串找到这个数,就sum++,最后利用sum,n和m来输出答案。
代码:
哈希:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int k=149993; //质数k
int a[k],sum,n,m,x;
int h(int x)
{
return x%k;
}
int locate(int x)
{
int o=h(x); //取余
int i=0;
while (i<k&&a[(o+i)%k]!=x&&a[(o+i)%k])
i++; //寻找第一个可以存放的位置(或是这个数的位置)
return (o+i)%k;
}
void insert(int x)
{
a[locate(x)]=x; //插入数字x
}
int pos(int x)
{
return a[locate(x)]==x; //寻找这个数字是否存在
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d",&x);
insert(x); //插入x
}
scanf("%d",&m);
for (int i=1;i<=m;i++)
{
scanf("%d",&x);
sum+=pos(x); //等于 if(pos(x)==1) sum++;
}
if (sum==n&&sum==m) printf("A equals B");
else if (sum<n&&sum==m) printf("B is a proper subset of A");
else if (sum==n&&sum<m) printf("A is a proper subset of B");
else if (sum==0) printf("A and B are disjoint");
else printf("I'm confused!"); //判断输出
return 0;
}
快排+二分:
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int a[120001],n,m,sum,x,l,r,mid;
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1); //排序
scanf("%d",&m);
for (int i=1;i<=m;i++)
{
scanf("%d",&x);
l=1;
r=n;
while (l<=r) //二分
{
mid=(l+r)/2; //中间数
if (a[mid]==x) //如果找到这个数
{
sum++; //计数
break; //推出二分
}
if (a[mid]<x) l=mid+1;
else r=mid-1;
}
}
if (sum==n&&sum==m) printf("A equals B");
else if (sum<n&&sum==m) printf("B is a proper subset of A");
else if (sum==n&&sum<m) printf("A is a proper subset of B");
else if (sum==0) printf("A and B are disjoint");
else printf("I'm confused!"); //输出
return 0;
}