A - カードゲーム 2 (Card Game 2) Editorial
by
blueberry1001
満点解法のみを解説します。 行いたい操作は以下です。
- \(A\)に含まれる数 \(x\)であって、\(x+3\) と \(x+6\) のどちらもが \(A\)に含まれるような \(x\)が存在するか判定する。
\(x\)の候補は\(A\)に含まれる数です。これは、for文などで\(A\)に含まれる要素を全て試せばよいです。
さて、ここで「\(x+3\) と \(x+6\) のどちらもが \(A\)に含まれる」という条件を判定したいです。ですが、存在判定をcount関数などの愚直で低速な方法で行うとTLEしてしまいます。
ここでset(集合型)というデータ構造を使うことを考えます。setを使うことで、
- 集合に要素を追加する。
- 集合に要素が存在するか判定する。
- 集合から要素を削除する
というような操作を、集合の要素数を\(N\)として計算量 \(O( \log_{}N)\) で行うことができます。setを使うことで行いたい操作を高速に行うことができ、ACすることができます。計算量は\(O(N \log N)\) となります。
コードは以下のようになります。(C++コードも下に記載しています。)
Pythonによる実装
N = int(input())
A = list(map(int,input().split()))
#Aの要素からなる集合型を宣言する。
s = set(A)
#答えが見つかったらansをTrueにする。
#最初はFalseにしておく。
ans = False
for x in A:
if x+3 in s and x+6 in s:
ans = True
if ans:
print("Yes")
else:
print("No")
C++による実装
#include<bits/stdc++.h>
using namespace std;
int main(){
//入力を受け取る
int n;cin >> n;
vector<int>a(n);
for(int i = 0;i<n;i++){
cin >> a[i];
}
//setを宣言する
set<int>s;
for(int i = 0;i<n;i++){
s.insert(a[i]);
}
bool ans = false;
for(int i = 0;i<n;i++){
if(s.count(a[i]+3)&&s.count(a[i]+6)){
ans = true;
}
}
if(ans)cout << "Yes" << endl;
else cout << "No" << endl;
}
posted:
last update: