Official

B - ペアを見つけよう / Find a Pair Editorial by physics0523 Editorial for printing


多様な解法が想定されますが、一例を示します。

C++ の multiset を利用します。
C++ の multiset を利用すると多重集合(要素に重複を許した集合)を管理することができます。

以下の手順で本問題に正解できます。

  • 多重集合 \(ms\) を準備する。
  • \(A\) の全ての要素を \(ms\) に追加する。
  • \(A\) の全ての要素 \(x\) について、以下を繰り返す。
    • \(ms\) から \(x\) をひとつ削除する。
    • 現時点で、 \(ms\) は \(x\) 以外の全ての \(A\) の要素を含んでいる状態になることに注意されたい。
    • この時点で \(ms\) に \(x+K\) あるいは \(x-K\) が含まれている場合は、その生徒と \(K\) 点差の別の生徒が存在することが分かるため、解に \(1\) 加算する。
    • \(ms\) に \(x\) をひとつ追加する。

本解法の時間計算量は \(O(N \log N)\) です。

どの解法を取るにせよ、 \(K=0\) の場合に注意してください。値 \(A_i+K\) あるいは \(A_i-K\) を検出しようとして、自身を検出してしまう可能性があります。

実装例 (C++):

#include<bits/stdc++.h>

using namespace std;

int main(){
  int N,K;
  cin >> N >> K;
  multiset<int> ms;
  vector<int> A(N);
  for(auto &nx : A){
    cin >> nx;
    ms.insert(nx);
  }
  int res=0;
  for(auto &nx : A){
    ms.erase(ms.find(nx));
    bool ok=false;
    if(ms.find(nx+K)!=ms.end()){ok=true;}
    if(ms.find(nx-K)!=ms.end()){ok=true;}
    if(ok){res++;}
    ms.insert(nx);
  }
  cout << res << "\n";
  return 0;
}

posted:
last update: