(구) 알고리즘 기초(백준 알고리즘 태그)/빠른 입출력

[빠른 입출력 기초]백준 빠른 A+B(15552번) 풀이 (C++/Python)

isekaipudding 2026. 1. 26. 15:02

이 글은 A+B 출력과 for문 반복 정도는 알고 있다고 가정하고, 빠른 입출력에 집중해서 설명하겠습니다.

 

백준 문제들을 풀다 보면 입력의 개수가 너무 많아서 시간 초과날 때가 있습니다.

예시로 백준 빠른 A+B(15552번) 문제를 해결하기 위해 A+B를 for문으로 여러 번 반복하는 소스 코드를 만든다고 가정합니다.

 

 

문제 : 빠른 A+B(15552번)(Bronze IV)
문제 링크 : https://www.acmicpc.net/problem/15552
출처 : Baekjoon Online Judge

 

아래에 제가 C++ 소스 코드 및 Python 소스 코드를 다음과 같이 짰다고 가정합니다.

[C++]

#include <bits/stdc++.h> // 자주 쓰는 표준 라이브러리를 한 번에 포함(백준/코테용)

using namespace std;     // std::를 매번 쓰지 않기 위해 생략

int main() {
    int t;
    cin >> t;

    while (t--) {
        int a, b;
        cin >> a >> b;
        cout << a + b << '\n';
    }

    return 0;
}

[Python]

T = int(input())
for _ in range(T) :
    A, B = map(int, input().split())
    print(A + B)

 

자, 해당 소스 코드들을 제출해보면 어떻게 될까요?

시원하게 시간 초과 받았습니다.

자, 이 문제를 해결할려면 어떻게 해야 할까요?

1개 입력받는 시간 자체를 줄이면 해결됩니다.

 

C++의 경우부터 확인합니다.

main 함수에 다음과 같은 두 줄 코드를 추가합니다.

ios::sync_with_stdio(false);
cin.tie(nullptr);

이 두 줄 코드의 의미는 무엇일까요?

각 코드는 다음과 같은 의미를 가지고 있습니다.

[1번째]

ios는 input/output stream의 줄임말로 쉽게 말해 C++에서 입출력을 담당한다고 보면 됩니다.

여기서 sync_with_stdio는 C언어의 stdio.h와 C++가 서로 동기화(sync) 되어 있다는 것을 의미합니다.

그리고 매개변수 안에 false가 들어갔다는 것은 "C와 C++는 서로 동기화하지 않는다"입니다.

C와 C++가 서로 동기화 되어 있다면 C언어의 scanf/printf 라인과 C++의 cin/cout 라인이 서로 교차할 때 생기는 지연 시간(delay)이 생깁니다. 그래서 이 동기화를 해제하여 오직 C++의 cin/cout 라인만 사용하도록 하여 지연 시간(delay)을 없애도록 합니다.

[2번째]

기본 상태일 때 cin과 cout은 서로 묶인 상태(tie)입니다.

cin으로 입력받을 때 마지막에 저장된 출력 메시지를 자동으로 flush하는 기능입니다.

이 방식의 장점은 대화형 프로그램 만들 때 원활한 대화를 할 수 있도록 즉각적인 반응을 할 수 있다는 점입니다.

하지만 이 방식의 단점은 cin이 엄청 많이 반복되는 경우 cout에서 불필요한 flush가 반복되어 느려지는 문제점이 생깁니다.

이런 경우 tie()의 매개변수 안에 nullptr를 추가하여 cin과 cout의 연결을 끊어버립니다.

이러면 불필요한 flush가 반복되는 것을 막을 수 있습니다.

 

추가로 백준 사이트에서 cin.tie(NULL);로 하는 경우도 있는데 cin.tie(nullptr);와 거의 비슷한 동작을 하나 딱 한 가지만 다릅니다.

cin.tie(nullptr); -> C++ 표준 포인터용 null입니다. 즉, C++에서 타입이 명확한 널 포인터입니다.

cin.tie(NULL); -> C언어에서 아무 값도 없다는 것을 의미하는 null 값입니다. 즉, 주로 C언어에서 해당 포인터는 null이라는 것을 의미합니다. 하지만 함수 오버로딩에서 때때로 정수 0으로 인식할 수 있는 사소한 가능성이 있어서 별로 권장하지는 않습니다.

 

하지만 백준에서는 기본적으로 nullptr이든 NULL이든 정상적으로 구현되므로 큰 문제는 없지만 되도록 nullptr을 권장합니다.

 

이렇게 해서 다음과 같은 C++ 코드가 만들어집니다.

#include <bits/stdc++.h> // 자주 쓰는 표준 라이브러리를 한 번에 포함(백준/코테용)

using namespace std;     // std::를 매번 쓰지 않기 위해 생략

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int t;
    cin >> t;

    while (t--) {
        int a, b;
        cin >> a >> b;
        cout << a + b << '\n';
    }

    return 0;
}

그 다음으로 Python으로 어떻게 하면 속도 최적화가 되는지 알아볼까요?

저같은 경우는 맨 윗 줄에 다음과 같은 코드 2줄을 추가합니다.

import sys

input = sys.stdin.readline

먼저 sys 모듈을 import합니다.

그 다음 코드는 sys.stdin(표준 입력)에 존재한 readline() 함수를 가져오는 것입니다.

여기서 readline()는 한 줄을 읽어오는 함수를 의미합니다.

sys.stdin.readline()를 input()로 재정의합니다.

즉, 기존의 input()는 sys.stdin.readline() 기능으로 덮여집니다.

 

그 다음 하나의 변수를 다음과 같이 입력합니다.

T = int(input().rstrip())

중간에 rstrip()을 추가한 이유는 readline()으로 받는 경우 개행 문자(\n)가 같이 입력되어 나중에 연산할 때 문제가 생깁니다.

그러므로 rstrip()(가장 오른쪽 문자 1개 제거)으로 개행 문자를 삭제합니다.

최종적으로 다음과 같이 소스 코드를 수정합니다.

import sys

input = sys.stdin.readline

T:int = int(input().rstrip())
for _ in range(T) :
    A, B = map(int, input().split())
    print(A + B)

여기서 저는 Python에 정적 타입을 선호해서 T:int 형식으로 작성했지만 Python은 정적 타입 명시 없이도 정상적으로 런타임 됩니다.

 

자, 이제 2개 소스 코드를 직접 제출해볼까요?

달콤한 AC(맞았습니다!!) 판정을 받았습니다!

 

앞으로 이 방식은 다른 코드에도 동일하게 적용하면 불필요한 시간 낭비를 막을 수 있어 코딩 테스트에서도 굉장히 큰 도움이 될 것입니다!

 

추가로 기본 템플릿을 제공하겠습니다.

[C++]

#include <bits/stdc++.h>

using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    return 0;
}

[Python]

import sys

input = sys.stdin.readline