SSL P1125 集合(normal)

题目大意:
给定两个集合A、B,集合内的任一元素x满足1 ≤ x ≤10^9 ,并且每个集合的元素个数不大于10^5个。我们希望求出A、B之间的关系。只需确定在B 中但是不在 A 中的元素的个数即可。

①排序+枚举:
1.分别从小到大排序。
2.然后For一波找出他们最大的公共元素个数。
3.按题目要求输出。
时间复杂度:O(2(N+M))

const
  maxn=100000;
var
  t,a,b:array[1..maxn] of longint;
  p,i,n,m,j:longint;

procedure qsort(l,r:longint);
  var
    i,j,key,temp:longint;
  begin
    if l>=r then exit;
    i:=l;j:=r;
    key:=a[(l+r) div 2];
    repeat
      while  (a[i]<key) do inc(i);
      while  (a[j]>key) do dec(j);
      if i<=j then
      begin
        temp:=a[i];a[i]:=a[j];a[j]:=temp;
        inc(i); dec(j);
      end;
    until i>j;
   if l<j then qsort(l,j);
   if i<r then qsort(i,r);
  end;

begin
  read(n); for i:=1 to n do read(a[i]);
  read(m); for i:=1 to m do read(b[i]);
  qsort(1,n); t:=a; a:=b; b:=t;
  qsort(1,m); t:=a; a:=b; b:=t;
  i:=1;
  j:=1;
  while (i<=n) and (j<=m) do
   begin
    if a[i]=b[j] then
     begin
      inc(p);
      inc(i);
      inc(j);
      continue;
     end
   else  if a[i]<b[j] then inc(i) else inc(j);
  end;
       if (n=m)and(p=n) then writeln('A equals B')
  else if (n<m)and(p=n) then writeln('A is a proper subset of B')
  else if (n>m)and(p=m) then writeln('B is a proper subset of A')
  else if p=0 then writeln('A and B are disjoint')
  else writeln('I''m confused!');
end.

②hash:
很容易我们可以发现,这题用hash可以更轻松的实现,我们用一个比较大的质数取模,如1000007,因为我们要明确hash使用空间换时间。
然后这题,现将A集合的N个数插入hash表中,然后将B集合的M个数判断是否在其中,在就累加1,最后就正常判断输出。

const
    modn=1000007;
var
    hash:array [0..modn] of longint;
    i,j,n,m,ans:longint;

function locate(k:longint):longint;
var
    i:longint;
begin
    i:=k mod modn;
    while (hash[i]<>0) and (hash[i]<>k) do inc(i);
    exit(i);
end;

procedure insert(k:longint);
begin
     hash[locate(k)]:=k;
end;

function check(k:longint):boolean;
begin
     if hash[locate(k)]=k then exit(true);
     exit(false);
end;

begin
    read(n);
    for i:=1 to n do
    begin
         read(j);
         insert(j);
    end;
    read(m);
    ans:=0;
    for i:=1 to m do
    begin
         read(j);
         if check(j) then inc(ans);
    end;
            if (n=m) and (ans=n) then writeln('A equals B')
       else if (n<m) and (ans=n) then writeln('A is a proper subset of B')
       else if (n>m) and (ans=m) then writeln('B is a proper subset of A')
       else if ans=0 then writeln('A and B are disjoint')
       else writeln('I''m confused!');
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值