[백준] 큐2 18258

Soohyeon B·2022년 11월 7일
0

알고리즘 문제 풀이

목록 보기
32/70

문제

정수를 저장하는 큐를 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.

명령은 총 여섯 가지이다.

push X: 정수 X를 큐에 넣는 연산이다.
pop: 큐에서 가장 앞에 있는 정수를 빼고, 그 수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.
size: 큐에 들어있는 정수의 개수를 출력한다.
empty: 큐가 비어있으면 1, 아니면 0을 출력한다.
front: 큐의 가장 앞에 있는 정수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.
back: 큐의 가장 뒤에 있는 정수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.

풀이 endl과 '\n'의 차이

풀이 1

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

int main (void){
    ios::sync_with_stdio(0);
    cin.tie(0);
  
    int n;
    cin >> n;
    
    queue<int> Q;
    
    while(n--){
        string cmd;
        cin >> cmd;
        if(cmd =="push"){
            int x;
            cin >>x;
            Q.push(x);
        }
        
        else if(cmd =="pop"){
            if(Q.empty()) cout <<-1<<endl;
            else{
                cout << Q.front()<<endl;
                Q.pop();
            }
        }
        else if(cmd =="size"){
            cout << Q.size() <<endl;
        }
        else if(cmd == "empty"){
            cout << Q.empty() << endl;
        }
        else if(cmd =="front"){
            if(Q.empty()) cout << -1 <<endl;
            else cout << Q.front()<<endl;
        }
        else{
            if(Q.empty()) cout << -1<<endl;
            else cout << Q.back()<<endl;
        }
    }
    
    return 0;
}

해당 코드에서는 줄 바꿈을 endl로 했다.
이 코드를 제출하니 계속 시간 초과가 난다.
왜일까?

endl과 '\n'의 차이
endl은 출력 버퍼를 비우고, '\n'은 출력 버퍼를 비우지 않는다.
예를 들어서

1. cout << 1 <<endl;
2. cout << 1 <<'\n';

endl의 경우에는 flush()함수 역할을 겸하기 때문에 1번 코드에서는 1을 출력하고 바로 endl 명령으로 출력버퍼를 싹 지우게 된다. 이 flush 과정 때문에 '\n'을 수행하는 것보다 속도가 느리다.

반대로 2번 코드에서는 출력 버퍼를 지우라는 명령이 없기 때문에 1을 출력한 후 버퍼가 다 찼을 때나 프로그램이 종료될 때 커널에 의해서 버퍼가 지워진다.

따라허 1번 풀이가 틀린 이유는 명령어 입력이 될 때마다 endl로 출력을 바로 하고 해당 출력 버퍼를 지우는 것 때문이다. 즉 출력 타이밍이 맞지 않아서 틀리는 것이다.

online debugger 기준으로 실행한 결과 풀이 1의 실행결과는 다음과 같다.

명령어가 하나씩 입력될 때마다 결과가 바로바로 출력되고 출력버퍼가 비워진다.


'\n'으로 줄바꿈을 한 풀이 2의 결과는 위와 같다. 모든 명령이 다 입력되었을 때 그때 출력 버퍼에 저장되었던 값들이 한번에 출력된다.

구글링 해보니 백준에서 endl의 사용으로 런타임에러가 종종 발생하는 것으로 보아 특별한 조건이 없을 때는 '\n'으로 줄바꿈을 수행하는 것이 더 나은 선택이 될 것이다.

풀이 2

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

int main (void){
    ios::sync_with_stdio(0);
    cin.tie(0);
  
    int n;
    cin >> n;
    
    queue<int> Q;
    
    while(n--){
        string cmd;
        cin >> cmd;
        if(cmd =="push"){
            int x;
            cin >>x;
            Q.push(x);
        }
        
        else if(cmd =="pop"){
            if(Q.empty()) cout <<-1<<'\n';
            else{
                cout << Q.front()<<'\n';
                Q.pop();
            }
        }
        else if(cmd =="size"){
            cout << Q.size() <<'\n';
        }
        else if(cmd == "empty"){
            if(Q.empty()) cout << 1<<'\n';
            else cout << 0 <<'\n';
        }
        else if(cmd =="front"){
            if(Q.empty()) cout << -1 <<'\n';
            else cout << Q.front()<<'\n';
        }
        else{
            if(Q.empty()) cout << -1<<'\n';
            else cout << Q.back()<<'\n';
        }
    }
    
    return 0;
}

참고

https://cocoon1787.tistory.com/135

profile
하루하루 성장하는 BE 개발자

0개의 댓글