본문으로 건너뛰기
Previous
Next
C++ 코딩테스트 팁 | '백준/프로그래머스' 합격하는 10가지 비법

C++ 코딩테스트 팁 | '백준/프로그래머스' 합격하는 10가지 비법

C++ 코딩테스트 팁 | '백준/프로그래머스' 합격하는 10가지 비법

이 글의 핵심

C++ 코딩테스트 팁 - "백준/프로그래머스" 합격하는 10가지 비법. C++ 코딩테스트 팁의 코딩테스트 필수 템플릿, 팁 1: 입출력 최적화, 팁 2: STL 컨테이너 활용를 실전 코드와 함께 설명합니다.

코딩테스트 필수 템플릿

#include <bits/stdc++.h>  // 만능 헤더 (대부분의 STL 포함)
using namespace std;

int main() {
    ios_base::sync_with_stdio(false);  // 입출력 속도 향상
    cin.tie(NULL);
    
    // 코드 작성
    
    return 0;
}

팁 1: 입출력 최적화

TLE(시간 초과) 방지

// ❌ 느린 코드
cout << x << endl;  // endl은 버퍼를 비워서 느림

// ✅ 빠른 코드
cout << x << '\n';  // \n 사용

대량 입력 처리

// 빠른 입력
int n;
cin >> n;
vector<int> v(n);
for (int& x : v) cin >> x;  // 참조 사용

팁 2: STL 컨테이너 활용

vector (동적 배열)

vector<int> v;
v.push_back(1);      // 끝에 추가
v.pop_back();        // 끝 제거
v.size();            // 크기
v[0];                // 접근 (빠름)

map (키-값 쌍)

map<string, int> m;
m[apple] = 100;
m.count("apple");    // 존재 여부 (0 or 1)
m.find("apple");     // 찾기

set (중복 없는 집합)

set<int> s;
s.insert(1);         // 추가
s.erase(1);          // 제거
s.count(1);          // 존재 여부

팁 3: 자주 쓰는 알고리즘

정렬

vector<int> v = {3, 1, 4, 1, 5};

// 오름차순
sort(v.begin(), v.end());

// 내림차순
sort(v.begin(), v.end(), greater<int>());

// 커스텀 정렬
sort(v.begin(), v.end(),  {
    return a > b;  // 내림차순
});

이진 탐색

vector<int> v = {1, 2, 3, 4, 5};

// 값 찾기
bool found = binary_search(v.begin(), v.end(), 3);

// 위치 찾기
auto it = lower_bound(v.begin(), v.end(), 3);
int index = it - v.begin();

순열/조합

vector<int> v = {1, 2, 3};

// 다음 순열
do {
    // v 출력
} while (next_permutation(v.begin(), v.end()));

팁 4: 시간복잡도 체크

입력 크기시간복잡도알고리즘
n ≤ 10O(n!)완전탐색
n ≤ 20O(2^n)비트마스크
n ≤ 500O(n^3)플로이드
n ≤ 2,000O(n^2)이중 루프
n ≤ 100,000O(n log n)정렬
n ≤ 1,000,000O(n)선형 탐색

팁 5: 자주 하는 실수

실수 1: int 오버플로우

// ❌ 오버플로우
int a = 1000000;
int b = 1000000;
int c = a * b;  // 오버플로우!

// ✅ long long 사용
long long c = (long long)a * b;

실수 2: 배열 범위 초과

// ❌ 위험한 코드
int arr[100];
arr[100] = 1;  // 범위 초과!

// ✅ vector 사용 (안전)
vector<int> v(100);
v[99] = 1;  // OK

실수 3: 초기화 안 함

// ❌ 쓰레기 값
int dp[100][100];
// dp[i][j] 사용 시 쓰레기 값

// ✅ 초기화
int dp[100][100] = {0};
// 또는
memset(dp, 0, sizeof(dp));

팁 6: 디버깅 팁

// 디버그 출력 (제출 전 삭제)
#define DEBUG
#ifdef DEBUG
    #define debug(x) cout << #x << " = " << x << endl
#else
    #define debug(x)
#endif

debug(n);  // "n = 10" 출력

팁 7: 자주 나오는 패턴

투 포인터

int left = 0, right = 0;
while (right < n) {
    // 조건 체크
    if (조건) {
        // 답 갱신
        left++;
    }
    right++;
}

슬라이딩 윈도우

int sum = 0;
for (int i = 0; i < k; i++) sum += arr[i];

for (int i = k; i < n; i++) {
    sum += arr[i] - arr[i-k];
    // 답 갱신
}

팁 8: 시험장 체크리스트

  • 입출력 최적화 (sync_with_stdio, cin.tie)
  • endl 대신 \n 사용
  • int 오버플로우 체크
  • 배열 범위 체크
  • 초기화 확인
  • 시간복잡도 계산
  • 엣지 케이스 테스트 (n=0, n=1)

팁 9: 백준 자주 나오는 유형

유형 1: 구현 (시뮬레이션)

// 예: 배열 회전, 시계 시뮬레이션
// 핵심: 문제를 정확히 이해하고 구현

대표 문제:

  • 백준 14499 (주사위 굴리기)
  • 백준 14503 (로봇 청소기)

:

  • 조건을 빠짐없이 체크
  • 디버그 출력으로 중간 상태 확인

유형 2: 그리디

// 예: 동전 거스름돈, 회의실 배정
// 핵심: 정렬 후 탐욕적 선택

vector<pair<int,int>> meetings;
sort(meetings.begin(), meetings.end(),  {
    return a.second < b.second;  // 끝나는 시간 기준 정렬
});

대표 문제:

  • 백준 11047 (동전 0)
  • 백준 1931 (회의실 배정)

유형 3: 동적 계획법 (DP)

// 예: 피보나치, 배낭 문제
// 핵심: 점화식 세우기

int dp[1001];
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
    dp[i] = dp[i-1] + dp[i-2];
}

대표 문제:

  • 백준 1003 (피보나치 함수)
  • 백준 9251 (LCS)

유형 4: 그래프 탐색 (BFS/DFS)

// BFS (최단 거리)
queue<int> q;
q.push(start);
visited[start] = true;

while (!q.empty()) {
    int cur = q.front();
    q.pop();
    
    for (int next : graph[cur]) {
        if (!visited[next]) {
            visited[next] = true;
            q.push(next);
        }
    }
}

대표 문제:

  • 백준 1260 (DFS와 BFS)
  • 백준 7576 (토마토)

팁 10: 자주 쓰는 STL 함수

최댓값/최솟값

int maxVal = *max_element(v.begin(), v.end());
int minVal = *min_element(v.begin(), v.end());

합계

int sum = accumulate(v.begin(), v.end(), 0);

중복 제거

sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());

역순 정렬

reverse(v.begin(), v.end());

개수 세기

int cnt = count(v.begin(), v.end(), target);

실전 문제 풀이 예시

예시 1: 두 수의 합 (백준 스타일)

문제: 배열에서 합이 target인 두 수 찾기

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

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    
    int n, target;
    cin >> n >> target;
    
    vector<int> arr(n);
    for (int& x : arr) cin >> x;
    
    // 투 포인터
    sort(arr.begin(), arr.end());
    int left = 0, right = n - 1;
    int count = 0;
    
    while (left < right) {
        int sum = arr[left] + arr[right];
        if (sum == target) {
            count++;
            left++;
            right--;
        } else if (sum < target) {
            left++;
        } else {
            right--;
        }
    }
    
    cout << count << '\n';
    return 0;
}

예시 2: 최대 부분 배열 합

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

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    
    int n;
    cin >> n;
    
    vector<int> arr(n);
    for (int& x : arr) cin >> x;
    
    // 카데인 알고리즘
    int maxSum = arr[0];
    int currentSum = arr[0];
    
    for (int i = 1; i < n; i++) {
        currentSum = max(arr[i], currentSum + arr[i]);
        maxSum = max(maxSum, currentSum);
    }
    
    cout << maxSum << '\n';
    return 0;
}

언어별 비교

특성C++PythonJava
속도⚡⚡⚡⚡⚡
난이도😰😊😐
STL강력간단보통
디버깅어려움쉬움보통

권장:

  • 시간 제한 빡빡 → C++
  • 빠른 구현 → Python
  • 안정성 → Java

FAQ

Q1: bits/stdc++.h는 무엇인가요?

A: GCC 전용 만능 헤더입니다.

장점:

  • 모든 STL 포함 (iostream, vector, algorithm 등)
  • 한 줄로 끝

단점:

  • GCC/Clang만 지원 (MSVC 불가)
  • 컴파일 느림

대안 (MSVC 등):

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <queue>

Q2: using namespace std는 써도 되나요?

A: 코딩테스트에서는 괜찮습니다.

코딩테스트:

using namespace std;  // OK (코드 짧게)

실무 프로젝트:

// 비추천 (이름 충돌 가능)
using namespace std;

// 권장
std::cout << "Hello" << std::endl;

Q3: 시간 초과가 자꾸 나요!

A: 다음을 확인하세요.

체크리스트:

  1. 입출력 최적화 (sync_with_stdio(false))
  2. endl 대신 \n 사용
  3. 시간복잡도 확인 (O(n^2)인데 n=100,000?)
  4. 불필요한 연산 제거
  5. STL 알고리즘 활용 (최적화되어 있음)

예시:

// ❌ O(n^2) - TLE
for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
        // ...
    }
}

// ✅ O(n log n) - 통과
sort(v.begin(), v.end());

Q4: 메모리 초과는 어떻게 해결하나요?

A: 메모리 사용량을 줄이세요.

체크리스트:

  1. 불필요한 배열 제거
  2. 배열 크기 최소화
  3. bool 배열 대신 bitset 사용
  4. 재귀 깊이 줄이기

예시:

// ❌ 메모리 초과
int arr[1000000][1000];  // 4GB!

// ✅ 필요한 만큼만
vector<int> arr(n);  // n개만 할당

Q5: 백준과 프로그래머스 차이는?

A: 입출력 방식이 다릅니다.

백준:

  • 표준 입출력 (cin, cout)
  • main 함수에서 직접 처리

프로그래머스:

  • 함수 구현 방식
  • 입출력은 자동 처리
// 백준 스타일
int main() {
    int n;
    cin >> n;
    cout << n << '\n';
}

// 프로그래머스 스타일
int solution(int n) {
    return n;
}

Q6: 코딩테스트 준비 기간은?

A: 실력에 따라 다릅니다.

초보자 (C++ 기초 있음):

  • 기간: 3-6개월
  • 하루: 2-3문제
  • 목표: 백준 실버~골드

중급자 (알고리즘 기초 있음):

  • 기간: 1-3개월
  • 하루: 3-5문제
  • 목표: 백준 골드~플래티넘

추천 순서:

  1. 브론즈 30문제 (1주)
  2. 실버 50문제 (1개월)
  3. 골드 30문제 (2개월)
  4. 기출 문제 풀이 (1개월)

같이 보면 좋은 글 (내부 링크)

이 주제와 연결되는 다른 글입니다.

관련 글

심화 부록: 구현·운영 관점

이 부록은 앞선 본문에서 다룬 주제(「C++ 코딩테스트 팁 | ‘백준/프로그래머스’ 합격하는 10가지 비법」)를 구현·런타임·운영 관점에서 다시 압축합니다. 도메인별 세부 구현은 글마다 다르지만, 입력 검증 → 핵심 연산 → 부작용(I/O·네트워크·동시성) → 관측의 흐름으로 장애를 나누면 원인 추적이 빨라집니다.

내부 동작과 핵심 메커니즘

flowchart TD
  A[입력·요청·이벤트] --> B[파싱·검증·디코딩]
  B --> C[핵심 연산·상태 전이]
  C --> D[부작용: I/O·네트워크·동시성]
  D --> E[결과·관측·저장]
sequenceDiagram
  participant C as 클라이언트/호출자
  participant B as 경계(런타임·게이트웨이·프로세스)
  participant D as 의존성(API·DB·큐·파일)
  C->>B: 요청/이벤트
  B->>D: 조회·쓰기·RPC
  D-->>B: 지연·부분 실패·재시도 가능
  B-->>C: 응답 또는 오류(코드·상관 ID)
  • 불변 조건(Invariant): 버퍼 경계, 프로토콜 상태, 트랜잭션 격리, FD 상한 등 단계별로 문장으로 적어 두면 디버깅 비용이 줄어듭니다.
  • 결정성: 순수 층과 시간·네트워크·스케줄에 의존하는 층을 분리해야 테스트와 장애 분석이 쉬워집니다.
  • 경계 비용: 직렬화, 인코딩, syscall 횟수, 락 경합, 할당·GC, 캐시 미스를 의심 목록에 둡니다.
  • 백프레셔: 생산자가 소비자보다 빠를 때 버퍼·큐·스트림에서 속도를 줄이는 신호를 어디에 둘지 정의합니다.

프로덕션 운영 패턴

영역운영 관점 질문
관측성요청 단위 상관 ID, 에러율·지연 p95/p99, 의존성 타임아웃·재시도가 대시보드에 보이는가
안전성입력 검증·권한·비밀·감사 로그가 코드 경로마다 일관적인가
신뢰성재시도는 멱등 연산에만 적용되는가, 서킷 브레이커·백오프·DLQ가 있는가
성능캐시·배치 크기·커넥션 풀·인덱스·백프레셔가 데이터 규모에 맞는가
배포롤백 룬북, 카나리/블루그린, 마이그레이션·피처 플래그가 문서화되어 있는가
용량피크 트래픽·디스크·FD·스레드 풀 상한을 주기적으로 검증하는가

스테이징은 데이터 양·네트워크 RTT·동시성을 프로덕션에 가깝게 맞출수록 재현율이 올라갑니다.

확장 예시: 엔드투엔드 미니 시나리오

앞선 본문 주제(「C++ 코딩테스트 팁 | ‘백준/프로그래머스’ 합격하는 10가지 비법」)를 배포·운영 흐름에 맞춰 옮긴 체크리스트입니다. 도메인에 맞게 단계 이름만 바꿔 적용할 수 있습니다.

  1. 입력 계약 고정: 스키마·버전·최대 페이로드·타임아웃·에러 코드를 경계에 둔다.
  2. 핵심 경로 계측: 요청 ID, 단계별 지연, 외부 호출 결과 코드를 로그·메트릭·트레이스에서 한 흐름으로 본다.
  3. 실패 주입: 의존성 타임아웃·5xx·부분 데이터·락 대기를 스테이징에서 재현한다.
  4. 호환·롤백: 설정/마이그레이션/클라이언트 버전을 되돌릴 수 있는지 확인한다.
  5. 부하 후 검증: 피크 대비 p95/p99, 에러율, 리소스 상한, 알림 임계값을 점검한다.
handle(request):
  ctx = newCorrelationId()
  validated = validateSchema(request)
  authorize(validated, ctx)
  result = domainCore(validated)
  persistOrEmit(result, idempotentKey)
  recordMetrics(ctx, latency, outcome)
  return result

문제 해결(Troubleshooting)

증상가능 원인조치
간헐적 실패레이스, 타임아웃, 외부 의존성, DNS최소 재현 스크립트, 분산 트레이스·로그 상관관계, 재시도·서킷 설정 점검
성능 저하N+1, 동기 I/O, 락 경합, 과도한 직렬화, 캐시 미스프로파일러·APM으로 핫스팟 확인 후 한 가지씩 제거
메모리 증가캐시 무제한, 구독/리스너 누수, 대용량 버퍼, 커넥션 미반납상한·TTL·힙/FD 스냅샷 비교
빌드·배포만 실패환경 변수, 권한, 플랫폼 차이, lockfileCI 로그와 로컬 diff, 런타임·이미지 버전 핀
설정 불일치프로필·시크릿·기본값, 리전스키마 검증된 설정 단일 소스와 배포 매트릭스 표준화
데이터 불일치비멱등 재시도, 부분 쓰기, 캐시 무효화 누락멱등 키·아웃박스·트랜잭션 경계 재검토

권장 순서: (1) 최소 재현 (2) 최근 변경 범위 축소 (3) 환경·의존성 차이 (4) 관측으로 가설 검증 (5) 수정 후 회귀·부하 테스트.

배포 전에는 git addgit commitgit pushnpm run deploy 순서를 권장합니다.


이 글에서 다루는 키워드 (관련 검색어)

C++, 코딩테스트, 백준, 프로그래머스, STL, 알고리즘, 등으로 검색하시면 이 글이 도움이 됩니다.