2024. 5. 8. 22:05ㆍ백준
문제 링크
17281번: ⚾
아인타 팀의 선수는 총 9명이 있고, 1번부터 9번까지 번호가 매겨져 있다. 아인타는 자신이 가장 좋아하는 선수인 1번 선수를 4번 타자로 미리 결정했다.
아인타는 각 선수가 각 이닝에서 어떤 결과를 얻는지 미리 알고 있다. 가장 많은 득점을 하는 타순을 찾고, 그 때의 득점을 구해보자.
www.acmicpc.net
풀이
이닝에서 얻을 수 있는 최대 결과가 딱히 공식으로 있지도 않고, 있더라도 몹시 복잡할 것 같다. 이닝 수가 최대 50밖에 되지 않고, 가능한 타순의 가짓수도 \(8!=40320\)이니(4번째 타순은 1번 타자로 고정이므로), 이 정도면 브루트 포스(brute force)로 풀어볼 만하다.
일단 타순의 경우 4번째 타순을 제외한 나머지 타순을 next_permutation
함수로 전부 돌려볼 수 있을 것이다. 반복문에서 각 타자의 이닝 결과를 얻는 데 조금 귀찮겠지만, 어려울 건 없다.
그리고 이닝 결과에 따른 진루와 점수 획득을 구현하는 게 또다른 핵심인데, 필자는 처음 풀 때 큐를 이용하여 구현하였다. 그런데 큐를 쓰니 실행 속도가 매우 느리게 찍히는 것이 아닌가. 그래서 다 풀고 다른 사람의 풀이를 참고했는데, 다들 배열로 진루를 구현하고 있었다. 그래서 동일하게 배열로 다시 구현한 결과, 실행 속도가 2배 이상으로 상당히 빨라졌다.
그래서 진루를 어떻게 구현하는지는 간단하다. 배열 원소 하나하나를 야구장의 각 루로 정의하고, 선수가 루에 있으면 true
, 없으면 false
로 한다. 그리고 안타면 각 원소값을 한 칸씩 이동, 2루타면 두 칸씩 이동하는 식으로 구현하면 된다. 만약 선수가 루를 한 바퀴 돌았을 때(true
인 원소가 이동해서 배열 범위를 벗어나려 할 때)는 1점을 추가하도록 한다.
시간 복잡도
최악의 경우(worst case)는 9번째 타자의 이닝 결과가 아웃(0)일 경우이며, 이때 한 이닝 당 같은 타순을 3바퀴 돌게 된다. 이것이 최대 50이닝 존재하여 야구 한 판을 이루고, 이러한 판이 타자 순번의 가짓수(\(8!=40320\))만큼 존재한다. 이를 종합하면 시간 복잡도는 \(O(8!\times 50\times 3)=O(6048000)\)이다.
소스코드
#include <iostream>
#include <algorithm>
#define NUM 9
using namespace std;
int N, ans;
int inning[50][NUM];
int order[] = {1, 2, 3, 4, 5, 6, 7, 8};
// 정해진 타순에 따라 야구하는 함수
int baseball() {
int id = 0, score = 0;
// 이닝 횟수만큼 반복
for(int i = 0; i < N; i++) {
int out = 0;
bool base[4] = {false, false, false, false};
// 한 이닝을 3아웃이 될 때까지 반복
while(out < 3) {
int result;
id %= NUM;
if(id < 3) result = inning[i][order[id]];
else if(id == 3) result = inning[i][0];
else result = inning[i][order[id - 1]];
if(result == 0) out++;
else {
base[0] = true;
for(int j = 0; j < result; j++) {
if(base[3]) score++;
for(int k = 2; k >= 0; k--) {
base[k + 1] = base[k];
}
base[0] = false;
}
}
id++;
}
}
return score;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> N;
for(int i = 0; i < N; i++) {
for(int j = 0; j < NUM; j++) {
cin >> inning[i][j];
}
}
do {
ans = max(ans, baseball());
} while(next_permutation(order, order + NUM - 1));
cout << ans;
return 0;
}
'백준' 카테고리의 다른 글
17143. 낚시왕 (0) | 2024.05.28 |
---|---|
5373. 큐빙 (0) | 2024.05.24 |
1351. 무한 수열 (1) | 2024.04.30 |
20166. 문자열 지옥에 빠진 호석 (0) | 2024.04.24 |
18869. 멀티버스 Ⅱ (0) | 2024.04.20 |