https://www.acmicpc.net/problem/17281
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static int N, ans = 0;
public static int[][] result;
public static int[] arr = new int[9], visited = new int[9];
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
// 1. 입력받기
N = Integer.parseInt(br.readLine());
result = new int[N][9];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < 9; j++) {
result[i][j] = Integer.parseInt(st.nextToken());
}
}
// 2. 중복 순열을 통해 타순 정하기
visited[0] = 1;
dfs(0); // 27 * 8!
System.out.println(ans);
}
private static void dfs(int depth) {
if (depth == 9) {
// 3. 이닝 반복하기
int cur = ining();
if (cur > ans) {
ans = cur;
}
return;
}
for (int i = 1; i < 9; i++) {
if (depth == 3) {
dfs(depth + 1);
break;
}
if (visited[i] == 0) {
visited[i] = 1;
arr[depth] = i;
dfs(depth + 1);
visited[i] = 0;
}
}
}
private static int ining() {
int cnt = 0;
int num = 0;
int[] ru;
for (int i = 0; i < N; i++) {
int out = 0;
ru = new int[3];
while (out < 3) {
int cur = arr[num]; // 현재 타석 타자 번호
int ta = result[i][cur]; // 현재 이닝의 타자 결과
switch (ta) {
case 1: // 안타
if(ru[2] == 1) // 3루에 타자가 있으면
cnt++;
for (int j = 1; j >= 0; j--) { // 뒤로 밀기
ru[j+1] = ru[j];
}
ru[0] = 1;
break;
case 2: // 2루타
for (int j = 1; j < 3; j++) {
if (ru[j] == 1) { // 2,3루에 타자가 있으면
ru[j] = 0; // 초기화
cnt++; // 점수 증가
}
}
if(ru[0] == 1) { // 1루에 타자가 있으면
ru[0] = 0;
ru[2] = 1; // 3루로 이동
}
ru[1] = 1;
break;
case 3: // 3루타
for (int j = 0; j < 3; j++) {
if (ru[j] == 1) { // 루에 타자가 있으면
ru[j] = 0; // 초기화
cnt++; // 점수 증가
}
}
ru[2] = 1;
break;
case 4: // 홈런
cnt++; // 자신은 들어옴
for (int j = 0; j < 3; j++) {
if (ru[j] == 1) { // 루에 타자가 있으면
ru[j] = 0; // 초기화
cnt++; // 점수 증가
}
}
break;
case 0:
out++;
break;
}
// 타순 돌기
if (num == 8) {
num = 0;
} else {
num++;
}
}
}
return cnt;
}
}
## 풀이 사항
풀이 일자: 2024.10.18
풀이 시간: 60분
채점 결과: 정답
예상 문제 유형: DFS, 구현
시간: 580 ms
메모리: 80520kb
## 풀이 방법
1. 중복 순열을 이용하여 타순을 설정한다. 이때 4번째 타순인 경우엔 반드시 1번타자가 들어가야 하므로 바로 재귀해준뒤 for문을 빠져나간다.
2. 매 이닝마다 while문을 돌며 점수를 계산한다. 이닝이 교체될때 타순이 항상 0번부터 시작되지 않고 바로 전 이닝 타자부터 시작하므로 타자번호를 for문 밬에서 관리해준다.
'코딩테스트 > JAVA' 카테고리의 다른 글
[백준 JAVA] 1074번: Z (0) | 2024.10.23 |
---|---|
[백준 JAVA] 4179번: 불! (0) | 2024.10.22 |
[백준 JAVA] 9370번: 미확인 도착지 (0) | 2024.10.16 |
[백준 JAVA] 9935번: 문자열 폭발 (0) | 2024.10.13 |
[백준 JAVA] 12100번: 2048 (Easy) (0) | 2024.10.11 |