[C++] 백준/Gold/1253. 좋다

2025. 3. 13. 21:03·C++/Coding Test

문제: 좋다 (백준 1253번)

문제 분석

이 문제는 주어진 수열에서 "좋은 수"의 개수를 찾는 문제이다.

  • 정의:
    수열의 한 원소가 다른 두 원소의 합으로 표현될 수 있다면, 그 원소를 "좋은 수"라고 한다.
  • 제한:
    • 한 원소는 자기 자신을 이용할 수 없다.
    • 같은 원소의 인덱스가 겹치면 안 된다.

문제의 핵심은 모든 가능한 두 원소의 합을 고려해, 해당 합이 수열 내의 다른 원소와 일치하는지 확인하는 것이다.


해결 방법

  1. 자료구조 준비:
    • 벡터 v: 입력받은 수들을 저장.
    • 딕셔너리 dict: 각 숫자에 대해 (인덱스, 상태)를 저장하는 unordered_map 사용.
      • 키: 해당 숫자
      • 값: 해당 숫자가 등장하는 인덱스와, 아직 "좋은 수" 후보로 남아있는지를 나타내는 불리언 값
        → true: 아직 후보
        → false: 이미 한 번 사용하여 "좋은 수"로 판별됨
  2. 두 원소의 합 탐색:
    • 모든 가능한 두 원소 $(v[i],v[j])$ (단, $i<j$)의 합을 계산한다.
    • 이 합(key)이 딕셔너리에 존재하는지 확인한다.
    • 만약 존재하면, 해당 키에 매핑된 벡터를 순회하며,
      • 인덱스가 $i$ 또는 $j$ 와 겹치지 않고,
      • 아직 후보 상태(true)라면 "좋은 수"로 판별하고, 상태를 false로 변경한 후,
      • 후보 수를 세어준다.
  3. 중복 처리:
    • 한 번 "좋은 수"로 판별된 원소는 이후 다시 카운트하지 않도록,
    • 해당 원소를 다시 후보 목록에서 제거(혹은 상태를 false로 변경)하여 중복 계산을 피한다.

코드 전체

#include <bits/stdc++.h>
using namespace std;

int main()
{
    ios_base::sync_with_stdio(false); 
    cin.tie(NULL); 
    cout.tie(NULL);
    
    int n; 
    cin >> n;
    
    // dict: 숫자를 key로, 해당 숫자의 인덱스와 사용 여부(bool)를 저장
    unordered_map<int, vector<pair<int, bool>>> dict;
    vector<int> v(n);
    int answer = 0;

    // 입력: 숫자와 인덱스 저장
    for (int i = 0; i < n; i++)
    {
        cin >> v[i];
        dict[v[i]].push_back({i, true});
    }

    // 모든 가능한 두 원소 (i, j) 선택 (i < j)
    for (int i = 0; i < n; i++)
    {
        for (int j = i + 1; j < n; j++)
        {
            int key = v[i] + v[j]; // 두 원소의 합
            // dict에 key가 존재하는 경우 검사
            if (dict.contains(key))
            {
                auto& vec = dict[key];
                vector<pair<int, bool>> new_vec;
                // key에 해당하는 모든 후보들에 대해
                for (pair<int, bool>& p : vec)
                {
                    // 이미 사용되지 않았고, 인덱스가 i, j와 겹치지 않으면
                    if (p.second && p.first != i && p.first != j)
                    {
                        p.second = false; // 이미 "좋은 수"로 판별됨
                        answer++;
                    }
                    // 아직 후보인 경우, new_vec에 유지
                    if (p.second) new_vec.push_back(p);
                }
                // 업데이트된 벡터로 교체하여 이후 불필요한 탐색을 줄임
                vec = move(new_vec);
            }
        }
    }

    cout << answer;
}

 

'C++ > Coding Test' 카테고리의 다른 글

[C++] 백준/Gold/2011. 암호코드  (0) 2025.03.19
[C++] 백준/Gold/1915. 가장 큰 정사각형  (0) 2025.03.14
[C++] 백준/Gold/2023. 신기한 소수  (0) 2025.03.12
[C++] 백준/Gold/14719. 빗물  (0) 2025.03.11
[C++] 백준/Gold/27172. 수 나누기 게임  (0) 2025.03.10
'C++/Coding Test' 카테고리의 다른 글
  • [C++] 백준/Gold/2011. 암호코드
  • [C++] 백준/Gold/1915. 가장 큰 정사각형
  • [C++] 백준/Gold/2023. 신기한 소수
  • [C++] 백준/Gold/14719. 빗물
돼지표
돼지표
https://github.com/wkdgns135
  • 돼지표
    돼지표 개발 스토리
    돼지표
  • 전체
    오늘
    어제
    • 분류 전체보기 (112)
      • C++ (60)
        • Coding Test (53)
        • Study (1)
      • Python (1)
      • Machine Learning (2)
      • Computer Graphics (4)
        • Curly Hair Simulation (2)
      • GPU Programming (11)
        • CUDA basic (7)
        • CUDA fluidsGL (4)
      • Unreal 5 (26)
        • Troubleshooting (4)
        • FPS Shooting (5)
        • Study (10)
        • EOS (1)
        • STILL LOADING (5)
      • Computer Science (7)
        • Algorithm (3)
      • Other (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    자료 구조
    C++
    UE5
    FPS
    BFS
    dp
    OpenGL
    구현
    정렬
    CS
    아이작 맵 생성
    CUDA
    GPU Programming
    Rendering Pipeline
    그래프 탐색
    unreal 5
    Algorithm
    STILL LOADING
    수학
    Fluid Simulation
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
돼지표
[C++] 백준/Gold/1253. 좋다
상단으로

티스토리툴바