- 문제
- 풀이
입력받은 값을 배열에 쭉 저장한 뒤, 두 값이 합쳐졌을 때 x가 되는 경우를 판단해야 하는 문제이다.
뭔가 답이 알듯말듯해서 혼자 고민하다가 다른 분의 풀이(https://github.com/encrypted-def/basic-algo-lecture/blob/master/0x03/solutions/3273.cpp) 를 참고했다. 이미 너무 깔끔한 코드인데 개인적으로 조건문 내부에서 사칙연산을 그대로 넣는 걸 좋아하지 않아서 value 변수로 따로 빼주었다.
#include <iostream>
using namespace std;
int a[1000001] = {};
bool occur[2000001];
int n, x;
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
int ans = 0;
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
cin >> x;
for (int i = 0; i < n; i++) {
int value = x - a[i];
if (value > 0 && occur[value]) ans++;
occur[a[i]] = true;
}
cout << ans;
}
풀이 코드에선 occur 배열을 사용해 이미 등장한 숫자를 기록하고, 이를 통해 각 숫자와 x를 만들 수 있는 수의 존재 여부를 빠르게 확인할 수 있다. 작동 원리는 다음과 같다.
1. 먼저 각 원소 a[i]에 대해 x - a[i]를 계산하여 occur[x - a[i]]의 값을 확인해 해당하는 값이 존재하는지 확인한다.
2. 만약 occur[x - a[i]]가 true이면, 이는 이전에 등장한 수 중 x - a[i]가 존재함을 의미한다. 따라서 a[i]와 x - a[i]의 합이 x가 되는 쌍이 존재하므로, ans를 1 증가시킨다.
3. 이후 occur[a[i]] = true;로 a[i]가 등장했음을 기록해준다.
중복 검사는 occur 배열을 통해 O(1) 시간에 이루어지고, 숫자의 등장 횟수를 따로 기록하였기 때문에 occur[x - a[i]]만 확인하므로 전체 시간 복잡도는 O(n)가 된다.
아이디어가 좋은 풀이라 다음에 비슷한 문제가 또 있으면 이걸 참고해서 혼자 풀어봐야겠다.
'코딩테스트 > 문제풀이' 카테고리의 다른 글
[백준/2442번/C++] 별 찍기 - 5 (0) | 2024.11.07 |
---|---|
[백준/10093번/C++] 숫자 (0) | 2024.11.05 |
[백준/1475번/C++] 방 번호 (0) | 2024.10.28 |
[백준/1267번/C++] 핸드폰 요금 (0) | 2024.10.27 |
[백준/2576번/C++] 홀수 (0) | 2024.10.27 |