반응형
문제 요약
플레이어가 두 명 있다. 각 플레이어의 카드 더미가 주어진다.
각 플레이어는 번갈아 가면서 본인의 그라운드에 본인의 카드 더미 제일 위에서 카드를 내려놓는다. 카드를 내려놓을 때 이미 그라운드에 카드가 놓여있었다면 이미 놓여있던 카드는 고려하지 않는다.
도중에 특정 조건을 만족하면 그라운드에 있는 카드들을 본인 카드 더미로 들고간다.
도도의 조건은 그라운드에 나와 있는 두 카드 중에 숫자가 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;
}
반응형
'Problem Solving > 문제풀이' 카테고리의 다른 글
백준 20925번 메이플스토리 (0) | 2021.02.27 |
---|---|
백준 20924번 트리의 기둥과 가지 (0) | 2021.02.27 |
백준 20922번 겹치는 건 싫어 (0) | 2021.02.27 |
백준 20921번 그렇고 그런 사이 (0) | 2021.02.27 |
백준 20920번 영단어 암기는 괴로워 (0) | 2021.02.27 |