본문 바로가기

Problem Solving/문제풀이

백준 20923번 숫자 할리갈리

반응형

문제 요약

플레이어가 두 명 있다. 각 플레이어의 카드 더미가 주어진다.

각 플레이어는 번갈아 가면서 본인의 그라운드에 본인의 카드 더미 제일 위에서 카드를 내려놓는다. 카드를 내려놓을 때 이미 그라운드에 카드가 놓여있었다면 이미 놓여있던 카드는 고려하지 않는다.

도중에 특정 조건을 만족하면 그라운드에 있는 카드들을 본인 카드 더미로 들고간다.

도도의 조건은 그라운드에 나와 있는 두 카드 중에 숫자가 5인 카드가 있는 것이고, 수연이의 조건은 그라운드의 나와있는 두 숫자의 합이 5가 되는 것이다. 단 비어있는 그라운드가 있어선 안된다.

도도가 먼저 이 과정을 시작한다. 한 사람이 승리하면 그라운드에 있는 카드들을 본인의 카드 더미 아래에 놓는다.

이런 과정을 반복할 때, 본인의 카드더미가 비게 되면 진다.

위 과정은 M번 반복한다고 할 때, 승자를 출력하자. 만약에 M번 진행한 후에 카드 더미가 비어있지 않다며 카드 더미에 카드 수가 더 많은 사람이 이긴다. 그 수가 같다면 비긴다.

풀이

문제 조건을 제대로 읽는 게 중요한 문제다. 그 뒤엔 그냥 구현 문제다.

카드 더미에 카드를 앞 뒤로 추가하게 된다. deque을 사용하면 이게 간편하게 된다. 그리고 한 사람이 카드 하나를 내려놓는 과정을 한 턴이라고 하면 M턴을 시뮬레이션한 뒤에 결과를 출력해야 한다.

이걸 잘못 읽어서 시간 안에 안 돌 거 같아서 코드를 안짜고 있었다.

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

deque<int> deck[2], ground[2];

int N, M;

int win_check() {
    if(ground[0].size() && ground[0].front() == 5) return 0;
    if(ground[1].size() && ground[1].front() == 5) return 0;
    if(ground[0].size() && ground[1].size() && ground[0].front() + ground[1].front() == 5) return 1;
    return -1;
}

int main() {
    cin.tie(nullptr); ios::sync_with_stdio(false);
    cin >> N >> M;
    for(int i=0;i<N;++i) {
        int a, b; cin >> a >> b;
        deck[0].push_front(a);
        deck[1].push_front(b);
    }
    int turn = 0;
    for(int i=0;i<M;++i) {
        ground[turn].push_front(deck[turn].front());
        deck[turn].pop_front();
        if (deck[turn].empty()) {
            cout << (turn ? "do" : "su") << '\n';
            return 0;
        }
        int w = win_check();
        if (w != -1) {
            int l = 1 - w;
            while (ground[l].size()) {
                deck[w].push_back(ground[l].back());
                ground[l].pop_back();
            }
            while (ground[w].size()) {
                deck[w].push_back(ground[w].back());
                ground[w].pop_back();
            }
        }
        turn = 1 - turn;
    }
    if(deck[0].size() > deck[1].size()) cout << "do" << '\n';
    else if(deck[0].size() < deck[1].size()) cout << "su" << '\n';
    else cout << "dosu" << '\n';
    return 0;
}
반응형