【NOIP2016复赛模拟赛】朋友

问题描述
mxy 即将前往新世界。
在前往新世界的过程中,ta 遇见了两种人。一种是只和lowb 做朋友,即当且仅当自己
的能力值大于对方时他们会成为朋友,另一种是大神我们做朋友,即当且仅当自己的能力
值小于对方时他们会成为朋友。
现在告诉你两种人的能力值。请你计算一共有多少对友好关系。
输入
每组测试数据有三行。
第一行有两个整数m,n(1 <= m,n <= 20000),分别代表前者人数和后者人数。
第二行m 个数,第三行n 个数,代表各自的能力值。
输出
一行一个整数,表示有多少对友好关系。
样例输入
5 3
8 1 7 3 1
3 6 1
样例输出
7
算法讨论
先将两种人的能力值从大到小排序,然后逐个比较,符合做朋友的就加一对,因为做朋友是相互的,所以只用做一次,再加几个优化:当I类人第一个能力值大于II类人最后一个,则直接加n;当I类人第一个能力值小于II类人最后一个,则直接跳过当前I类人,往下继续找。初评没有过……自以为是的加了个所谓的优化,头在往后找时尾在往前找,当然这样是错的……

const
  maxn=20000;
type
  arr=array[1..maxn] of longint;
var
  a,b:array[1..maxn] of longint;
  i,j,q,p,n,m:longint;
  s:int64;

procedure qsort(var x:arr;l,r:longint);
var
  i,j,m,t:longint;
begin
  i:=l; j:=r;
  m:=x[(l+r) div 2];
  repeat
    while x[i]>m do
      inc(i);
    while x[j]do
      dec(j);
    if i<=j
      then begin
             t:=x[i];
             x[i]:=x[j];
             x[j]:=t;
             inc(i); dec(j)
           end;
  until i>j;
  if lthen qsort(x,l,j);
  if ithen qsort(x,i,r);
end;

begin
  assign(input,'friend.in'); reset(input);
  assign(output,'friend.out'); rewrite(output);
  read(n,m);
  for i:=1 to n do
    read(a[i]);
  for i:=1 to m do
    read(b[i]);
  qsort(a,1,n);
  qsort(b,1,m);
  for i:=1 to n do
    begin
      q:=1; p:=m;
      if b[q]then begin
               inc(s,m);
               continue
             end;
      if b[p]>=a[i]
        then break;
      while a[i]<=b[q] do
        inc(q); 
      if a[i]>b[q]
        then begin
               s:=s+(m-q+1);
               continue
             end;
      if a[i]>b[p]
        then begin
               s:=s+(m-p+1);
               continue
             end;
    end;
  writeln(s);
  close(input); close(output)
end.

【NOIP2016复赛模拟赛】朋友_第1张图片
Pixiv ID:61676992

你可能感兴趣的:(排序,暴力)