article thumbnail image
Published 2022. 9. 22. 17:57

문제: https://www.acmicpc.net/problem/3273

 

 

 

 

: 처음 제출한 코드

#include <iostream>
#include <vector>
using namespace std;
int main()
{
  int n, x, result = 0;
  int arr[100000];
  cin >> n;
  for (int i = 0; i < n; i++)
    cin >> arr[i];
  cin >> x;

  for (int i = 0; i < n - 1; i++)
    for (int j = i + 1; j < n; j++)
      (arr[i] + arr[j] == x) && result++;

  cout << result << '\n';
}

문제를 보자마자 시간복잡도 O(n²)인 풀이가 가장 먼저 떠올랐다.

수열 a를 arr 배열에 담고, 이중 반복문을 사용해서 a[i]와 a[j]를 더해가며 x와 같은 쌍이 나오면 result를 1증가시키는 방법으로 작성했다.

하지만 O(n²)이기 때문에 n의 크기가 커질수록 문제 해결에 걸리는 시간이 급격히 커지게 되면서 시간 초과됐다.

 

 

 

: 나중에 제출한 코드

#include <algorithm>
#include <iostream>
using namespace std;

int check[2000001] = {};
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  
  int n, x, result = 0;
  int a[100000];
  
  cin >> n;
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    check[a[i]]++;
  }
  cin >> x;
  for (int i = 0; i < n; i++)
    if ((x > a[i]) && check[x - a[i]]) result++;
  cout << result / 2;
}

O(n²)으로는 해결할 수 없는 문제이기 때문에 O(n) 풀이를 생각해야 한다.

꽤 오랜시간 고민해봤지만 그럴듯한 아이디어 조차 떠오르지 않아서 바킹독의 풀이를 봤다.

바킹독은 occur이라는 배열을 선언하고 수열 값들의 존재 유무를 체크하는 용도로 사용했다.

바킹독의 풀이를 보고 나도 코드를 작성해봤다.

먼저 a 배열에 수열을 담고, check 배열에 1을 할당했다.

다음으로 a[i]가 x보다 작아야지만 합이 x가 되는 다른 짝을 찾을 수 있기 때문에 x > a[i]을 조건으로 걸어두고, check[x-a[i]]를 참조해서 합이 x가 되는 다른 짝이 존재하는지 체크한다.

존재한다면 result의 값을 1증가시켜준다.

이때 result는 a[i] = ai일 때랑 a[i] = aj일 때 각각의 짝이 2번 카운트된 것이기 때문에 중복을 없애기 위해 2로 나눠야 한다. 

 

 

 

: 수정한 코드

#include <algorithm>
#include <iostream>
using namespace std;
int a[100000];
bool check[2000001] = {};
int n, x;
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int result = 0;
  cin >> n;
  for (int i = 0; i < n; i++) cin >> a[i];
  cin >> x;
  for (int i = 0; i < n; i++) {
    if (x > a[i] && check[x - a[i]]) result++;
    check[a[i]] = 1;
  }
  cout << result;
}

수정한 코드에서는 result를 2로 나누지 않는다.

애초에 중복으로 카운트를 하지 않기 때문이다.

합이 x를 만족하는 두 수를 (ai, aj)라고 할 때 a[i] = ai에서 aj가 check배열에 표시되지 않았더라도 a[i] = aj에서 ai가 check배열에 표시되어 있기 때문에 한 번만 카운트될 수 있기 때문이다.

 

 

 

 

 

 

'알고리즘' 카테고리의 다른 글

[BOJ] 1406: 에디터  (0) 2022.09.28
[BOJ] 10808: 알파벳 개수  (0) 2022.09.23
[BOJ] 1475: 방 번호  (0) 2022.09.22
[BOJ] 2577: 숫자의 개수  (0) 2022.09.22
[BOJ] 2562: 최댓값  (1) 2022.09.21
복사했습니다!