developer-ellen
인간 디버거의 로그 찍기
developer-ellen
전체 방문자
오늘
어제
  • 분류 전체보기 (217)
    • 회고록 (0)
    • 취뽀 및 커리어 여정의 Stack (2)
      • SSAFY 7기 (2)
    • 프로그래밍공부 (24)
      • c++ (0)
      • JAVA (3)
      • Spring (5)
      • design pattern (3)
      • BackDB (1)
      • Servlet&JSP (3)
      • Vue (4)
      • JPA (4)
      • Infra (1)
      • Linux (0)
    • AI (3)
      • papers (3)
      • trend (0)
    • 프로젝트진행 (0)
      • 데이터베이스 (0)
      • 서버개발 (0)
      • 인공지능 (0)
      • 하루정리 (0)
    • 포트폴리오 (0)
    • 알고리즘 (158)
      • 알고리즘문풀 (155)
      • 알고리즘공부 (3)
    • 통계공부 (15)
      • 시계열분석 (15)
      • 회귀분석 (0)
    • CS (14)
      • 컴퓨터네트워크 (4)
      • 운영체제 (8)
      • 데이터베이스 (2)
    • 주저리주저리 (0)
      • 필사 (0)
    • 취업관련정보 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 삼성코테자바풀이
  • 삼성코테구현문제추천
  • Arima
  • 삼성코테파이썬
  • 삼성코테기출
  • 운영체제인터럽트
  • 데이터분석
  • 카카오코테java풀이
  • 삼성코테파이썬풀이
  • c++디자인패턴
  • 삼성코테자바준비
  • 시계열분석
  • 삼성코테구현풀이
  • 삼성코테준비
  • 삼성코테자바꿀팁
  • c++ 빌더 패턴
  • 백준파이썬풀이
  • 삼성코테파이썬준비
  • SW역량테스트파이썬풀이
  • 통계학
  • 카카오코테
  • AR모형
  • SW역량테스트파이썬
  • 삼성코테기출자바풀이
  • ARIMA모형
  • 시계열
  • 코테파이썬
  • MA모형
  • 통계분석
  • BOJ파이썬풀이

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
developer-ellen

인간 디버거의 로그 찍기

알고리즘/알고리즘문풀

BOJ - 주사위 윷놀이 17825번 (python, JAVA)

2021. 10. 18. 23:04

❓ 문제 - 백준 주사위 윷놀이 17825번 - python, JAVA 풀이법

 

출처 

(https://www.acmicpc.net/problem/17825)

 

17825번: 주사위 윷놀이

주사위 윷놀이는 다음과 같은 게임판에서 하는 게임이다. 처음에는 시작 칸에 말 4개가 있다. 말은 게임판에 그려진 화살표의 방향대로만 이동할 수 있다. 말이 파란색 칸에서 이동을 시작하면

www.acmicpc.net

 

 

📝 문제해결법

1. 이 문제는 구현+BFS(중복순열)로 풀었다.

  • 일단 게임판의 인덱스로 다음 연결되는 인덱스의 정보를 connect 리스트에 저장한다.
  • 1 ~ 20은 시작부터 도착 전까지 외곽지역을 나타내며, 21은 도착인데 자기 자신을 가리키게 저장한다. 또한 22 ~ 24는 10 점의 파란색 안쪽의 지역을 인덱스로 나타내고, 25 ~ 26은 20점 안쪽의 지역을 나타내고, 27 ~ 29는 30점 안쪽의 지역을 인덱스로 나타낸다. 또한 30 ~ 32는 가운데 25점 부터 40점 전까지의 지역을 나타내는 인덱스이다.
  • board 리스트를 통해 각 지역 인덱스에 속한 점수들을 나타낸다.
  • dul 리스트로 각 지역마다 말이 존재하는지 존재하지 않는지를 나타낸다.
  • DFS(중복순열)을 돌려 4**10 가지 경우를 다 탐색하여 어떤 말을 10번 골랐을 때 최대 점수를 얻을 수 있는지 최대값을 계속 갱신해서 정답을 출력한다.

2. BFS(중복순열)로 풀었다.

  • depth로 말을 고른 횟수를 나타내며 총 10번 말을 골랐을 때 지금까지 얻었던 점수와 현재까지 최대 점수를 비교해서 최대값으로 갱신한 후 리턴한다.
  • 4가지 말에 대해서 모두 다 탐색할 수 있도록 하는데, 고른 말의 현재 위치에서 주사위만큼을 이동시킨 후, 이동시킨 지역이 만약 도착지역이 아니면서 말이 이미 존재한다면 그 말을 고르는 것을 취소한다.
  • 고른 말의 현재 위치에서 주사위만큼 이동시키는 방법은 만약 말의 현재 위치가 5, 10, 15번 인덱스(파란지역이여서 방향을 변경하는 곳)이면 해당 지역 다음을 가리키는 곳으로 인덱스를 변경해준다. 그 후 이동시켰으므로 이동해야하는 주사위의 값을 -1 해준다.
  • 그리고 현재 위치에서 말을 이동시켰을 때도 외곽 지역이라면 이동시킬 만큼만 더해서 이동 위치의 인덱스를 구하고, 만약 현재 위치가 파란색 지역에서 시작했을 때는 connect 리스트를 활용하여 다음 이동 위치의 인덱스를 구한다.
  • 그 말을 골랐다고 했을 때, 현재 위치의 말이 존재하지 않음으로, 이동될 지역에 말이 존재함으로, 현재 말의 위치 정보를 담은 리스트를 변경한다. 이동시킨 후의 위치에 해당하는 점수를 더하고 depth +1 해준 후 dfs를 호출한다. 

3. 문제 풀면서 느낀점

  • 각 지역을 다음 연결될 인덱스를 리스트에 저장하여 연결시킨다는 점이 특이했다. 이런 방법도 기억해놔야겠다.

 

💻 소스코드 (python)

# 주사위 윷놀이 - BOJ 17825
# BFS + 구현
dice = list(map(int, input().split()))

horse = [0, 0, 0, 0]

connet = [0 for _ in range(33)]
# 외곽(1 ~ 20)
for i in range(21):
    connet[i] = i+1
# 도착
connet[21] = 21
# 10번 다음 (22 ~ 24)
connet[22], connet[23], connet[24] = 23, 24, 30
# 20번 다음 (25 ~ 26)
connet[25], connet[26] = 26, 30
# 30번 다음 (27 ~ 29)
connet[27], connet[28], connet[29] = 28, 29, 30
# 가운데(25) ~ 40전
connet[30], connet[31], connet[32] = 31, 32, 20

# 점수
board = [0 for _ in range(33)]
for i in range(1, 21):
    board[i] = i * 2
board[21] = 0
board[22], board[23], board[24] = 13, 16, 19
board[25], board[26] = 22, 24
board[27], board[28], board[29] = 28, 27, 26
board[30], board[31], board[32] = 25, 30, 35
dul = [0 for _ in range(33)]
def dfs(depth, score):
    global score_max
    if depth == 10:
        score_max = max(score_max, score)
        return

    for i in range(4):
        # 말 현재 위치에서 주사위 만큼 이동
        x, now_x, num = horse[i], horse[i], dice[depth]
        if x in [5, 10, 15]:
            if x == 5:
                x = 22
            elif x == 10:
                x = 25
            else:
                x = 27
            num -= 1
        if x + num <= 21:
            x += num
        else:
            for _ in range(num):
                x = connet[x]
        if dul[x] and x != 21:
            continue
        dul[now_x], dul[x], horse[i] = 0, 1, x
        dfs(depth+1, score+board[x])
        dul[now_x], dul[x], horse[i] = 1, 0, now_x
score_max = 0
dfs(0, 0)
print(score_max)

 

💻 소스코드 (JAVA)

// BOJ - 주사위 윷놀이(17825번)
// DFS + 구현

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main_17825 {
	public static int[] dice;
	public static int ans;
	
	public static int[] connect;
	public static int[] score;
	public static boolean[] check;
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		dice = new int[10];
		String[] data = br.readLine().split(" ");
		for(int i=0;i<10;i++) {
			dice[i] = Integer.parseInt(data[i]);
		}
		
		connect = new int[33];
		score = new int[33];
		
		for(int i=0;i<21;i++) {
			connect[i] = i+1;
			score[i] = i*2;
		}
		// 도착
		connect[21] = 21;
		score[21] = 0;
		
		// 10 안  (22 ~ 24)
		connect[22] = 23;
		connect[23] = 24;
		connect[24] = 30;
		score[22] = 13;
		score[23] = 16;
		score[24] = 19;
		
		// 20 안 (25 ~ 26)
		connect[25] = 26;
		connect[26] = 30;
		score[25] = 22;
		score[26] = 24;
		
		// 30 안 (27 ~ 32)
		connect[27] = 28;
		connect[28] = 29;
		connect[29] = 30;
		connect[30] = 31;
		connect[31] = 32;
		connect[32] = 20;
		
		score[27] = 28;
		score[28] = 27;
		score[29] = 26;
		score[30] = 25;
		score[31] = 30;
		score[32] = 35;
		
		ans = 0;
		check = new boolean[33];
		dfs(new int[5], 0, 0);
		System.out.println(ans);
	}
	
	public static void dfs(int[] horse, int depth, int sum) {
		if(depth == 10) {

			ans = Math.max(ans, sum);
			return;
		}
		
		for(int i=0;i<5;i++) {
			int x = horse[i];
			int now = horse[i];
			int move = dice[depth];

			if(x == 5) {
				x = 22;
				move--;
			} else if(x==10) {
				x = 25;
				move--;
			} else if(x==15) {
				x = 27;
				move--;
			}

			if(x+move <= 21) {
				x += move;
			} else {
				for(int m=0;m<move;m++) {
					x = connect[x];
				}
			}
	
			
			if(check[x] &&  x != 21) {
				continue;
			}

			check[x] = true;
			check[now] = false;
			horse[i] = x;
		
			dfs(horse, depth+1, sum+score[x]);
			
			check[x] = false;
			check[now] = true;
			horse[i] = now;
			

		}
	}
	

}

'알고리즘 > 알고리즘문풀' 카테고리의 다른 글

BOJ - 청소년 상어 19236번 (python)  (2) 2021.10.19
BOJ - 모노미노도미노2 20061번 (python)  (0) 2021.10.19
BOJ - 원판 돌리기 17822번 (python)  (0) 2021.10.18
BOJ - 새로운 게임2 17837번 (python)  (0) 2021.10.18
BOJ - 게리맨더링2 17779번 (python, JAVA)  (0) 2021.10.17
    '알고리즘/알고리즘문풀' 카테고리의 다른 글
    • BOJ - 청소년 상어 19236번 (python)
    • BOJ - 모노미노도미노2 20061번 (python)
    • BOJ - 원판 돌리기 17822번 (python)
    • BOJ - 새로운 게임2 17837번 (python)
    developer-ellen
    developer-ellen

    티스토리툴바