백준 17281 - 야구 게임⚾
3 minute read
문제링크
문제설명
- 9명으로 이루어진 두 팀이 야구 게임을 진행한다.
- 총 N이닝 동안 게임을 진행해야 하고, 한 이닝에 3아웃이 발생하면 이닝이 종료되고 공격과 수비를 교대한다.
- 경기 시작 전 타순을 정해야 하고, 경기 중에는 타순을 변경할 수 없다.
- 9번 타자까지 공을 쳤는데 3아웃이 발생하지 않은 상태면 이닝은 끝나지 않고, 1번 타자부터 다시 타석에 선다.
- 타순은 이닝이 변경되어도 유지되어야한다. 2이닝에 6번 타자가 마지막 타자였다면, 3이닝은 7번 타자부터 타석에 선다.
- 공을 쳐서 얻는 결과는 다음과 같다.
- 안타(1): 타자와 모든 주자가 한 루씩 진루한다.
- 2루타(2): 타자와 모든 주자가 두 루씩 진루한다.
- 3루타(3): 타자와 모든 주자가 세 루씩 진루한다.
- 홈런(4): 타자와 모든 주자가 홈까지 진루한다.
- 아웃(0): 모든 주자는 진루하지 못하고, 공격 팀에 아웃이 하나 증가한다.
- 선수는 1번부터 9번까지 번호가 있고, 1번 선수는 4번타자로 고정한 채 다른 선수의 타순을 모두 결정해야 한다.
- 각 선수가 각 이닝에서 어떤 결과를 얻는지가 주어질 때, 가장 많은 득점을 하는 타순을 찾고 그 때의 득점을 구하라.
문제접근
- 1번 선수는 4번 타자로 고정이 되어 있으므로, 2번~9번 선수들을 1~3번 타자, 5~9번 타자에 배치를 해야 한다.
- 타순을 구하는 경우의 수는 백트래킹을 활용하여 순열을 구하였고, 타순이 완성되면 모든 이닝을 수행한다.
- 각 이닝마다 선수들의 결과는
table[inning][number]
배열로 관리하였다.
- 주자들의 상태를 파악하기 위한
runner[4]
배열을 만들어서 1루~3루에 주자가 있는지 확인하고, 타자의 결과에 따라 움직일 수 있도록 구현했다.
- 주자들이 움직이고 나면 타자도 움직여야 한다는 점에 주의하자.
구현
#include <iostream>
#include <vector>
#include <algorithm>
#include <memory.h>
using namespace std;
int N;
int cand[9]; // cand[8]=1 : 4번 타자는 1번 선수로 고정
bool visited[8] = { false, };
int player[8] = { 2, 3, 4, 5, 6, 7, 8, 9 };
int table[51][10]; // 1번 선수부터 9번 선수까지 이닝별 결과
int playGame() {
// 타순 설정
int hitPlayers[10];
for (int i = 0; i < 3; i++) {
hitPlayers[i + 1] = cand[i];
}
// 4번 타자 고정
hitPlayers[4] = cand[8];
for (int i = 3; i < 8; i++) {
hitPlayers[i + 2] = cand[i];
}
int runner[4] = { 0, 0, 0, 0 }; // 주자 상태
int ret = 0;
int idx = 1;
for (int inning = 1; inning <= N; inning++) {
int outCnt = 0;
memset(runner, 0, sizeof(runner));
while (true) {
int number = hitPlayers[idx++];
int status = table[inning][number];
// 다음 타순 설정. out count 계산 및 탈출 조건
if (idx == 10) idx = 1;
if (status == 0) outCnt++;
if (outCnt == 3) break;
if (status == 1) {
// 주자 이동
for (int i = 3; i >= 1; i--) {
if (i >= 3 && runner[i]) {
ret++;
runner[i] = 0; // 3루수는 들어옴
}
else if (runner[i]) {
runner[i + 1] = 1;
runner[i] = 0;
}
}
runner[1] = 1; // 타자 이동
}
else if (status == 2) {
for (int i = 3; i >= 1; i--) {
if (i >= 2 && runner[i]) {
ret++;
runner[i] = 0;
}
else if (runner[i]) {
runner[i + 2] = 1;
runner[i] = 0;
}
}
runner[2] = 1;
}
else if (status == 3) {
for (int i = 3; i >= 1; i--) {
if (runner[i]) {
ret++;
runner[i] = 0;
}
}
runner[3] = 1;
}
else if (status == 4) {
for (int i = 3; i >= 1; i--) {
if (runner[i]) ret++;
runner[i] = 0;
}
ret++;
}
}
}
return ret;
}
int setPlayer(int cnt) {
if (cnt == 8) {
return playGame();
}
int ret = 0;
for (int i = 0; i < 8; i++) {
if (visited[i]) continue;
visited[i] = true;
cand[cnt] = player[i];
ret = max(ret, setPlayer(cnt + 1));
visited[i] = false;
}
return ret;
}
int main()
{
cin.tie(NULL);
ios_base::sync_with_stdio(false);
scanf("%d", &N);
for (int i = 1; i <= N; i++) {
for (int num = 1; num <= 9; num++) {
scanf("%d", &table[i][num]);
}
}
cand[8] = 1;
printf("%d\n", setPlayer(0));
}
Leave a comment