[백준/boj] 2493번: 탑 | C++

2023. 12. 24. 16:33·백준 문제풀이

오른쪽부터 반복문을 도는 형식 & 반복 횟수를 줄여야 함(의미없는 연산을 하지 않도록)-> 스택을 이용

 

목차

    1. 문제풀이 핵심

    2. 문제풀이 코드

    2-1. 로직 설명

    3. 문제풀이에 사용된 함수

    3-1. stack<pair<자료형,자료형>>

     


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

     

    2493번: 탑

    첫째 줄에 탑의 수를 나타내는 정수 N이 주어진다. N은 1 이상 500,000 이하이다. 둘째 줄에는 N개의 탑들의 높이가 직선상에 놓인 순서대로 하나의 빈칸을 사이에 두고 주어진다. 탑들의 높이는 1

    www.acmicpc.net

    문제풀이 핵심

    이중 for 문을 사용하게 되면 시간복잡도가 O(n^2) 이 되며 1.5초를 넘어 시간초과가 뜨게 된다.

    따라서 O(n)의 시간 복잡도를 가진 로직을 생각해내는것이 핵심이다.

     

    O(n)의 시간복잡도를 충족하기 위해서는 문제에서 주어지는 탑 높이 입력을 다 받은 후에 후처리를 하는 것이 아닌

    높이를 입력 받는 동시에 높이 비교 연산을 진행해야겠다는 생각을 하는게 문제풀이의 핵심이었다.


    문제풀이 코드

    #include<iostream>
    #include<stack>
    
    using namespace std;
    
    stack<int> topList;
    stack<int> topNum;
    int n;
    
    int main(){
        ios::sync_with_stdio(0);
        cin.tie(0);
        
        cin >>n;
    
        int f;
        cin >>f;
    
        topList.push(f);
        topNum.push(1);
        cout << '0' <<' ';
    
        for(int i =1;i<n;i++){
            int newTop;
    
            cin >> newTop;
    
            //오른쪽(새로 들어온 값)이 왼쪽(top)보다 큰 경우
            while(!topList.empty()&& newTop >= topList.top()){
                //기존 top 없앰
                topList.pop();
                topNum.pop();
            }
            
            if(topNum.empty()){
                cout << '0'<<' ';
            }else{
                cout << topNum.top()<<' ';
            }
    
            topNum.push(i+1);
            topList.push(newTop);
        }
        return 0;
    }

    로직 설명

    탑 높이 입력에서 먼저 입력받은 값보다 더 큰 값을 나중에 입력받으면 먼저 입력받은 값은 더이상 사용되지 않는 값이 된다. 

    문제 자체가 오른쪽부터 본인보다 큰 가장 가까운 수를 찾는 문제이기 때문이다. 

     

    따라서 탑의 높이를 입력받으며 기존의 topList 스택의 top()인 요소와 새로 입력받은 요소중에 새로 입력받은 것이 더 큰 값이면 기존의 topList 에 존재하는 값과 그 탑의 순서를 의미하는 topNum의 top()값을 pop()하여 삭제한다. 이과정은 topList 가 빈 배열이 되거나(왼쪽 끝까지 돌았는데 본인보다 높은 탑이 없는 경우) topList에서 새로 입력받은 값보다 큰 값을 찾을때까지 반복된다. (위 코드의 while문)

     

    while 문을 탈출 했을 때 그 이유가 topList.empty()라면 입력받은 탑 기준 왼쪽에 본인보다 높은 탑이 없는것이기에 0을 출력해주고 그게 아니라면 본인보다 높은 탑을 찾은것이므로 topNum()의 top()값을 출력해준다. 

     

    그 후 topNum과 topList에 현재 입력받은 값을 넣어준다. 


     

    문제풀이에 사용된 함수

    STL stack 을 사용했다

    stack 라이브러리에서 push(),top(),pop(),empty() 함수를 사용하였다


     

    stack <pair < 자료형,자료형>>

    스택에 두개의 값을 묶어서 저장하는 방식이다. 

     

    이 문제에서 탑의 높이와 탑의 순서를 같이 저장해야 하는 경우에 사용하면 좋다.

    이걸 몰라서 나는 스택 두개를 사용했는데 이걸 이용하면 스택하나로 높이와 순서를 모두 저장할 수 있고

    push, pop 등의 관리도 한번에 처리할 수 있기 때문에 로직상의 간결함을 잡고 공간복잡도 줄일 수 있는 방법이다.

     


     

    마무리

    시간복잡도를 생각하며 로직을 짜는게 까다로운 문제였다..

     

     

    '백준 문제풀이' 카테고리의 다른 글

    [백준/boj] 1012번: 유기농 배추 | C++  (1) 2024.01.07
    [백준/boj] 2178번: 미로 탐색 | C++  (1) 2023.12.30
    [백준/boj] 2504번: 괄호의 값 | C++  (1) 2023.12.29
    [백준/boj] 2309번: 일곱 난쟁이 | C++  (0) 2023.12.19
    [백준/boj] 1152번: 단어의 개수 | C++  (5) 2023.12.18
    '백준 문제풀이' 카테고리의 다른 글
    • [백준/boj] 2178번: 미로 탐색 | C++
    • [백준/boj] 2504번: 괄호의 값 | C++
    • [백준/boj] 2309번: 일곱 난쟁이 | C++
    • [백준/boj] 1152번: 단어의 개수 | C++
    c_jm
    c_jm
    • c_jm
      c_jm
      c_jm

      🎋 어제보다 발전한 오늘

    • 전체
      오늘
      어제
      • 분류 전체보기 (36)
        • 프로젝트 (6)
        • 백준 문제풀이 (19)
        • 프로그래머스 문제풀이 (4)
        • 공부 (1)
        • 문제 해결 (2)
        • 기타 (4)
    • 블로그 메뉴

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

    • 공지사항

    • 인기 글

    • 태그

      코드블럭
      리버스 프록시
      docker
      도커컴포즈
      복붙
      reverse proxy
      인라인 css
      docker-compose.yml
      docker-compose
      nginx
      html
      백준 #1152 #c++
      jquery
      티스토리 다크모드
      리버스 프록시 서버
      도커
      홈서버
      글자색
      다크모드
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    c_jm
    [백준/boj] 2493번: 탑 | C++
    상단으로

    티스토리툴바