STL, 입출력, 반복/조건 처리

언리얼 거토
|2025. 10. 14. 23:19

1. 스택 문제 (백준 10828)

문제

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

명령은 총 다섯 가지이다.

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

입력

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지 않은 명령이 주어지는 경우는 없다.

 

출력

출력해야하는 명령이 주어질 때마다, 한 줄에 하나씩 출력한다.

 

예제 입력

7
pop
top
push 123
top
pop
top
pop

예제 출력

-1
-1
123
123
-1
-1

 

내 제출:

#include <iostream>   // 입출력을 위한 헤더
#include <vector>     // 스택을 구현하기 위해 vector 사용
#include <string>     // 명령어("push", "pop" 등)를 문자열로 처리하기 위해 사용
using namespace std;

int main() {
    // C++ 입출력 속도 향상 (백준 필수 세팅)
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;  // 명령의 개수를 저장할 변수
    if (!(cin >> n)) return 0;  // 입력이 실패하면 프로그램 종료

    vector<int> st;  // 스택 역할을 할 vector (후입선출, LIFO 구조)
    string cmd;      // 명령어를 저장할 변수

    // 명령어 개수(n)만큼 반복
    while (n--) {
        cin >> cmd;  // 명령어 입력

        if (cmd == "push") {
            // push X : 스택에 정수 X를 넣는 명령
            int x; 
            cin >> x;         // 넣을 값 입력
            st.push_back(x);  // 벡터의 맨 뒤에 삽입 (스택의 top에 넣는 것과 동일)
        }
        else if (cmd == "pop") {
            // pop : 스택의 가장 위(top)에 있는 정수를 빼고 출력
            if (st.empty()) 
                cout << -1 << '\n';  // 스택이 비어있으면 -1 출력
            else {
                cout << st.back() << '\n';  // 맨 위 값 출력
                st.pop_back();              // 맨 위 값 제거
            }
        }
        else if (cmd == "size") {
            // size : 스택에 들어있는 정수의 개수 출력
            cout << st.size() << '\n';
        }
        else if (cmd == "empty") {
            // empty : 스택이 비어있으면 1, 아니면 0 출력
            cout << (st.empty() ? 1 : 0) << '\n';
        }
        else if (cmd == "top") {
            // top : 스택의 가장 위에 있는 정수 출력 (제거는 안 함)
            if (st.empty()) 
                cout << -1 << '\n';  // 비어있으면 -1
            else 
                cout << st.back() << '\n';  // 맨 위 값 출력
        }
    }

    return 0;  // 프로그램 정상 종료
}

2. 요세푸스 문제 (백준 1158)

문제

요세푸스 문제는 다음과 같다.

1번부터 N번까지 N명의 사람이 원을 이루면서 앉아있고, 양의 정수 K(≤ N)가 주어진다. 이제 순서대로 K번째 사람을 제거한다. 한 사람이 제거되면 남은 사람들로 이루어진 원을 따라 이 과정을 계속해 나간다. 이 과정은 N명의 사람이 모두 제거될 때까지 계속된다. 원에서 사람들이 제거되는 순서를 (N, K)-요세푸스 순열이라고 한다. 예를 들어 (7, 3)-요세푸스 순열은 <3, 6, 2, 7, 5, 1, 4>이다. N과 K가 주어지면 (N, K)-요세푸스 순열을 구하는 프로그램을 작성하시오.

 

입력

첫째 줄에 N과 K가 빈 칸을 사이에 두고 순서대로 주어진다. (1 ≤ K ≤ N ≤ 5,000)

 

출력

예제와 같이 요세푸스 순열을 출력한다.

 

예제 입력

7 3

예제 출력

<3, 6, 2, 7, 5, 1, 4>

내 제출:

#include <iostream>
#include <queue>
using namespace std;

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

    int n, k;
    cin >> n >> k;  // N과 K 입력

    queue<int> q;   // 원을 표현하기 위한 큐

    // 1 ~ N까지 큐에 순서대로 넣기
    for (int i = 1; i <= n; i++) {
        q.push(i);
    }

    cout << '<';  // 출력 형식의 시작 괄호

    // 큐가 빌 때까지 반복 (모든 사람이 제거될 때까지)
    while (!q.empty()) {
        // K-1번째 사람까지 맨 뒤로 보냄
        for (int i = 0; i < k - 1; i++) {
            q.push(q.front()); // 맨 앞의 사람을 맨 뒤로 보내기
            q.pop();           // 맨 앞 제거
        }

        // 이제 K번째 사람은 제거될 차례
        cout << q.front(); // 제거되는 사람 출력
        q.pop();           // 큐에서 제거

        if (!q.empty()) cout << ", "; // 남은 사람이 있다면 쉼표 출력
    }

    cout << '>';  // 출력 형식의 끝 괄호
    return 0;
}

3. 괄호 문제 (백준 9012)

문제

괄호 문자열(Parenthesis String, PS)은 두 개의 괄호 기호인 ‘(’ 와 ‘)’ 만으로 구성되어 있는 문자열이다. 그 중에서 괄호의 모양이 바르게 구성된 문자열을 올바른 괄호 문자열(Valid PS, VPS)이라고 부른다. 한 쌍의 괄호 기호로 된 “( )” 문자열은 기본 VPS 이라고 부른다. 만일 x 가 VPS 라면 이것을 하나의 괄호에 넣은 새로운 문자열 “(x)”도 VPS 가 된다. 그리고 두 VPS x 와 y를 접합(concatenation)시킨 새로운 문자열 xy도 VPS 가 된다. 예를 들어 “(())()”와 “((()))” 는 VPS 이지만 “(()(”, “(())()))” , 그리고 “(()” 는 모두 VPS 가 아닌 문자열이다. 

여러분은 입력으로 주어진 괄호 문자열이 VPS 인지 아닌지를 판단해서 그 결과를 YES 와 NO 로 나타내어야 한다. 

입력

입력 데이터는 표준 입력을 사용한다. 입력은 T개의 테스트 데이터로 주어진다. 입력의 첫 번째 줄에는 입력 데이터의 수를 나타내는 정수 T가 주어진다. 각 테스트 데이터의 첫째 줄에는 괄호 문자열이 한 줄에 주어진다. 하나의 괄호 문자열의 길이는 2 이상 50 이하이다. 

출력

출력은 표준 출력을 사용한다. 만일 입력 괄호 문자열이 올바른 괄호 문자열(VPS)이면 “YES”, 아니면 “NO”를 한 줄에 하나씩 차례대로 출력해야 한다. 

 

예제 입력

6
(())())
(((()())()
(()())((()))
((()()(()))(((())))()
()()()()(()()())()
(()((())()(

 

예제 출력

NO
NO
YES
NO
YES
NO

 

내 제출:

#include <iostream>
#include <string>
#include <stack>   // 스택 사용
using namespace std;

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

    int t;              // 테스트 케이스 수
    cin >> t;

    while (t--) {
        string s;       // 괄호 문자열
        cin >> s;
        stack<char> st; // 괄호 검사용 스택
        bool isValid = true; // 올바른 괄호 여부 판단 플래그

        for (char c : s) {
            if (c == '(') {
                // 여는 괄호면 스택에 push
                st.push(c);
            }
            else if (c == ')') {
                // 닫는 괄호일 때
                if (st.empty()) {
                    // 짝이 맞는 여는 괄호가 없으면 잘못된 문자열
                    isValid = false;
                    break;
                }
                st.pop(); // 짝이 맞으면 pop
            }
        }

        // 모든 문자를 처리한 후에도 스택에 '('가 남아있으면 잘못된 괄호
        if (!st.empty()) isValid = false;

        cout << (isValid ? "YES" : "NO") << '\n';
    }

    return 0;
}

'C++' 카테고리의 다른 글

클린코딩  (0) 2025.03.27
브루트포스 기법  (0) 2025.03.11
STL 기본 구조  (0) 2025.02.18