반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
Tags
- 백준 파티
- 특수목적기구
- 경제기사 읽기
- KFO
- 행크TV
- 황농문 서울대교수
- 웅덩이 매매법
- 경제적 자유를 위한 5가지 공부법
- 백준 1238
- 구해줘월부
- 업무지구별
- 원금리스크
- 경제 기사읽기
- 급여액
- 연방준비제도(FRS)/연방준비은행(FRB)
- 정체성 만들기
- 한국직업개발원
- 역행자
- 매일경제
- 제로금리정책
- 엥겔의법칙
- 경제금융용어
- 유전자오작동
- 부동산기사읽기
- 평균급여액
- 이중통화채(dual currency bond)
- 월부TV
- 부동산 기사읽기
- 자발적 실업
- 자의식 해체
Archives
- Today
- Total
록키의 No Pain, No Gain
[BOJ] 17825 주사위 윷놀이 본문
반응형
https://www.acmicpc.net/problem/17825
17825번: 주사위 윷놀이
첫째 줄에 주사위에서 나올 수 10개가 순서대로 주어진다.
www.acmicpc.net
작년 삼성 하반기 기출문제
2달 전쯤에 풀었는데, 그 때 예외케이스를 찾지 못해서 못 푼 상태로 끝났었다.
그 상태로 방치해뒀다가 이번에 아예 새로 풀었는데 한번에 통과했다.
그 전에 고민 많이 했던 문제라 문제에 대한 분석이 확실 했던 듯 하다.
원래 알던 문제라 문제를 읽는 과정, 주의해야 할 부분에서 얻어갈 것은 별로 없었고 그냥 구현력만 좀 향상시킬 수 있었다..
문제
말이 4개 있고, 1~5까지 있는 주사위를 던져서 나올 수 10개를 미리 알고 있을 떄, 얻을 수 있는 최댓값 구하기
풀이
그냥 중복순열 그리고 시뮬레이션 그 자체.
말판 및 여러가지 필요한 정보들을 어떤 자료구조에 저장할지를 조금 고민 했었고
파란 화살표를 타고 가는 경우 등 예외의 경우를 처리할게 좀 있었다.
- 먼저, 4개의 말(0~3)을 중복 순열로 10개 뽑는다. 이때 i번째 말은 i번째 주사위 숫자 만큼 이동할 것이다.
- 각각의 경우에 대해서 턴 마다, 말들을 이동시킨다. 이 때 조심할 것은 다음에 이동할 칸에 이미 말이 있으면 그 경우는 배제해야한다.
- 얻을 수 있는 점수의 최댓값을 구한다.
실수 했던 부분
- 다음에 이동할 칸에 말이 있을 경우 return해 주어야 하는데, continue 해주어서 엄청나게 틀렸었다.
- 말판 가운데에 있는 25, 30, 35, 40과 같은 경우 내가 설정한 말판 구조에 의하면, 이미 말판이 올려져 있는 칸 위에 말판을 올리는 경우가 있었는데, 주의 해야 한다.
- exist[i][j] = true 하는 과정을 빼먹었다.
- 또한 초기화 관련하여 실수할 뻔..
실수 줄여서 한번에 통과하자..................
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
using namespace std;
int answer;
int dice[10];
int turn[10];
vector<vector<int>> board =
{ {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40},
{10, 13, 16, 19, 25, 30, 35, 40},
{20, 22, 24, 25, 30, 35, 40},
{30, 28, 27, 26, 25, 30, 35, 40}};
bool exist[4][21];
pair<int,int> position[4];
void game() {
int sum = 0;
for (int i = 0; i < 10; i++) {
int cur = turn[i];
int boardNum = position[cur].first;
int pos = position[cur].second;
int nextPos = pos + dice[i];
//이미 도착한 경우
if (position[cur].first == -1) continue;
//도착한 경우
if (nextPos >= board[boardNum].size()) {
exist[boardNum][pos] = false;
position[cur] = { -1,-1 };
continue;
}
//다음에 가야할 지점이 10인 경우
if (boardNum == 0 && board[boardNum][nextPos] == 10) {
if (exist[1][0]) return;
exist[0][pos] = false;
sum += 10;
position[cur] = { 1, 0 };
exist[1][0] = true;
continue;
}
//다음에 가야할 지점이 20인 경우
if (boardNum == 0 && board[boardNum][nextPos] == 20) {
if (exist[2][0]) return;
exist[0][pos] = false;
sum += 20;
position[cur] = { 2, 0 };
exist[2][0] = true;
continue;
}
//다음에 가야할 지점이 30인 경우
if (boardNum == 0 && board[boardNum][nextPos] == 30) {
if (exist[3][0]) return;
exist[0][pos] = false;
sum += 30;
position[cur] = { 3, 0 };
exist[3][0] = true;
continue;
}
//다음에 가야할 지점이 25, 30, 35인 경우
if (board[boardNum][nextPos] == 25 || board[boardNum][nextPos] == 30 ||
board[boardNum][nextPos] == 35) {
if (board[boardNum][nextPos] == 25 && (exist[1][4] || exist[2][3] || exist[3][4])) return;
if (board[boardNum][nextPos] == 30 && (exist[1][5] || exist[2][4] || exist[3][5])) return;
if (board[boardNum][nextPos] == 35 && (exist[1][6] || exist[2][5] || exist[3][6])) return;
exist[boardNum][pos] = false;
sum += board[boardNum][nextPos];
position[cur] = { boardNum, nextPos };
exist[boardNum][nextPos] = true;
continue;
}
//다음에 가야할 지점이 40인 경우
if (board[boardNum][nextPos] == 40) {
if (exist[0][20] || exist[1][7] || exist[2][6] || exist[3][7]) return;
exist[boardNum][pos] = false;
sum += 40;
position[cur] = { boardNum, nextPos };
exist[boardNum][nextPos] = true;
continue;
}
//그 외의 경우
if (exist[boardNum][nextPos]) return;
exist[boardNum][pos] = false;
sum += board[boardNum][nextPos];
position[cur] = { boardNum, nextPos };
exist[boardNum][nextPos] = true;
}
answer = max(answer, sum);
}
void init() {
for (int i = 0; i < 4; i++) {
position[i] = { 0, 0 };
for (int j = 0; j < 21; j++) {
exist[i][j] = false;
}
}
}
void dfs(int depth) {
if (depth == 10) {
init();
game();
return;
}
for (int i = 0; i < 4; i++) {
turn[depth] = i;
dfs(depth + 1);
}
}
int main() {
for (int i = 0; i < 10; i++) cin >> dice[i];
dfs(0);
cout << answer << "\n";
return 0;
}
반응형
'알고리즘' 카테고리의 다른 글
[BOJ] 17471번 게리멘더링 (0) | 2020.04.28 |
---|---|
[BOJ] 17822번 원판 돌리기 (0) | 2020.04.28 |
[BOJ] 17142번 연구소 3 (0) | 2020.04.26 |
[BOJ] 16895번 Maaaaaaaaaze (0) | 2020.04.25 |
[BOJ] 18809 Gaaaaaaaaaarden (0) | 2020.04.21 |
Comments