[백준 17825번 C/C++] 주사위 윷놀이
[백준 17825번 C/C++] 주사위 윷놀이
https://www.acmicpc.net/problem/17825
해결전략
백트래킹 Backtracking
이 문제는 풀지 못하고 다른 사람의 풀이를 보았다.
백트래킹 문제인건 인지하였지만 문제 조건을 세팅하는게 힘들었다. 주어진 숫자들을 다소 하드코딩하여 배열로 세팅하는 과정이 필요하였다. 아래와 같이 6개의 배열을 준비하여 사용한다. 이 부분이 생각하기 힘들었다.
- vector<int> dice(10); // 주사위 눈금
- vector<int> player(4); // 4개의 말이 위치한 칸의 번호
- vector<int> location(34); // 각 칸에서 다음 칸으로 이동할 때의 인덱스
- vector<int> score(34); // 각 칸의 점수
- vector<int> turn(34); // 파란색 화살표가 있는 칸에서 다른 경로로 바꿀 인덱스
- vector<bool> bPresent(34, false); // 각 칸에 말이 존재하는지 여부
정답코드
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int answer; // 최대 점수를 저장할 변수
vector<int> dice(10); // 주사위 눈금
vector<int> player(4); // 4개의 말이 위치한 칸의 번호
vector<int> location(34); // 각 칸에서 다음 칸으로 이동할 때의 인덱스
vector<int> score(34); // 각 칸의 점수
vector<int> turn(34); // 파란색 화살표가 있는 칸에서 다른 경로로 바꿀 인덱스
vector<bool> bPresent(34, false); // 각 칸에 말이 존재하는지 여부
void BackT(int cnt, int sum)
{
if (cnt == 10) { // 주사위를 모두 사용했을 때
answer = max(answer, sum); // 최대 점수 갱신
return;
}
for (int i = 0; i < 4; i++) // 4개의 말에 대해 반복
{
int prev = player[i]; // 현재 말의 위치
int cur = prev;
int move = dice[cnt]; // 이번에 이동할 주사위 눈금
if (turn[cur] > 0) { // 현재 위치가 파란색 화살표 지점이라면
cur = turn[cur]; // 경로 전환
move--; // 이동 횟수 1 감소
}
while (move--) { // 남은 이동횟수만큼 이동
cur = location[cur];
}
if (cur != 21 && bPresent[cur]) continue; // 도착 칸이 아니고, 이미 다른 말이 있는 칸이라면 이동 불가
bPresent[prev] = false; // 이전 위치를 비움
bPresent[cur] = true; // 현재 위치에 말을 놓음
player[i] = cur; // 말의 위치 갱신
BackT(cnt + 1, sum + score[cur]); // 재귀 호출로 다음 주사위 눈금 처리
// 백트래킹을 위해 상태 복원 (4개의 말에 대해 반복해야 하니 복원함)
player[i] = prev;
bPresent[prev] = true;
bPresent[cur] = false;
}
}
void GivenInfo()
{
// 윷놀이 판의 기본 구성 설정
for (int i = 0; i < 27; i++) {
location[i] = i + 1;
}
location[21] = 21; // 도착 칸 설정
// 특수 경로 설정
location[27] = 20; location[28] = 29; location[29] = 30;
location[30] = 25; location[31] = 32; location[32] = 25;
// 파란색 화살표가 있는 칸에서 다른 경로로 전환하는 설정
turn[5] = 22; turn[10] = 31; turn[15] = 28;
// 각 칸의 점수 설정
for (int i = 0; i < 21; i++) {
score[i] = 2 * i;
}
// 특수 경로의 점수 설정
score[22] = 13; score[23] = 16; score[24] = 19;
score[25] = 25; score[26] = 30; score[27] = 35;
score[28] = 28; score[29] = 27; score[30] = 26;
score[31] = 22; score[32] = 24;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
GivenInfo();
for (int i = 0; i < 10; i++){
cin >> dice[i];
}
BackT(0, 0);
cout << answer << "\n";
return 0;
}
풀이를 참고한 곳
'⭐ 코딩테스트 > 백준' 카테고리의 다른 글
[백준 24337번 C/C++] 가희와 탑 (0) | 2024.04.09 |
---|---|
[백준 2931번 C/C++] 가스관 (1) | 2024.04.08 |
[백준 17136번 C/C++] 색종이 붙이기 (0) | 2024.03.26 |
[백준 2623번 C/C++] 음악 프로그램 (0) | 2024.03.21 |
[백준 3015번 C/C++] 오아시스 재결합 (0) | 2024.03.16 |
댓글
이 글 공유하기
다른 글
-
[백준 24337번 C/C++] 가희와 탑
[백준 24337번 C/C++] 가희와 탑
2024.04.09 -
[백준 2931번 C/C++] 가스관
[백준 2931번 C/C++] 가스관
2024.04.08 -
[백준 17136번 C/C++] 색종이 붙이기
[백준 17136번 C/C++] 색종이 붙이기
2024.03.26 -
[백준 2623번 C/C++] 음악 프로그램
[백준 2623번 C/C++] 음악 프로그램
2024.03.21