[ 백준 2818 ] 숙제하기 싫을 때 : C++ 풀이
백준 2818 풀이입니다.
[ 백준 2818 ] 숙제하기 싫을 때 : C++ 풀이
풀이
결국엔 어떻게 돌리느냐는 위 아래 눈이 무엇인지 가 중요 합니다.
내말은 돌려도 변하지 않는 면이 있는데, 그 면들을 중심으로 번호가 어떻게 변하는지 4개의 수의 반복이 어케되는지를 매겨놓으면 문제해결이 가능합니다.
처음 주사위 상태는
1
2
3
4
5
5 (굴려도 변하지 않는 앞쪽면)
1 (윗면)
2 (굴려도 변하지 않는 뒤쪽면)
이렇게 되고, 주사위를 굴리다가 다음 행으로 옮기게 되면 주사위의 상태는 아래처럼 변할 것입니다.
1
2
3
4
5
(마지막 윗면 상태 의 반대편)
(이전 윗면)
(마지막 윗면 상태)
또 그 다음은
1
2
3
4
5
(마지막 윗면 상태의 반대편)
N
(마지막 윗면상태)
이런식으로 반복됨을 알 수 있습니다.
그렇다면, 1 4 6 3과 같은 옆면의 수열을 어떻게 구할 수 있느냐가 이제 관건인데, 사실 주사위기 때문에 경우의 수가 그렇게 많지 않습니다.
저의 경우는 아예 계산을 해서 프리셋을 먼저 생성해놓고 풀었는데요, 아래와 같이 반복되는 수열이 정의됩니다.
! 오른쪽으로 굴리는 기준 !
1
2
3
4
5
6
(5, 2) 일 경우 {1, 4, 6, 3}
(2, 5) 일 경우 {1, 3, 6, 4}
(1, 6) 일 경우 {3, 2, 4, 5}
(6, 1) 일 경우 {3, 5, 4, 2}
(3, 4) 일 경우 {1, 5, 6, 2}
(4, 3) 일 경우 {1, 2, 6, 5}
구상한 알고리즘
행이 홀수일 경우
(a, b) 값을 얻는다. (이때 a와 b는 수열에 관여하지 않는 위에서 봤을때 기준 주사위의 앞, 뒷면 이다.)
이전 판의 a 값을 가져온다. 이 값이 현재 상태의 윗면이다.
열의 크기를 4로 나눈 몫과 14(전체 수열의 투어 결과)를 곱한 값을 결과에 더한다.
열의 크기를 4로 나눈 나머지값만큼 더 굴린다.
while(remain--) {}
굴리는 원리는 첫 윗면의 idx 값을 가져와서, idx = (idx + 1) % 4; 와 같은 방식으로 더해나가면 된다.
행일 짝수일 경우
- 수열을 얻는 과정은 똑같이 진행하나, idx = (idx - 1 >= 0 ? idx - 1 : 3) % 4; 과 같이 전개하면 된다.
소스코드
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<iostream>
#include<vector>
using namespace std;
vector<int> preset[7][7];
int main() {
int front = 5, back = 2;
int up = 1;
preset[5][2] = { 1, 4, 6, 3 };
preset[2][5] = { 1, 3, 6, 4 };
preset[1][6] = { 3, 2, 4, 5 };
preset[6][1] = { 3, 5, 4, 2 };
preset[3][4] = { 1, 5, 6, 2 };
preset[4][3] = { 1, 2, 6, 5 };
int n, m; cin >> n >> m;
long long ans = 0;
for (int i = 1; i <= n; ++i) {
ans += (m / 4) * 14;
int remain = m % 4;
int idx = -1;
for (int i = 0; i < 4; ++i) {
if (preset[front][back][i] == up) {
idx = i;
}
}
while (remain--) {
int next_value = preset[front][back][idx];
ans += next_value;
if (remain) {
if(i%2) idx = (idx + 1) % 4;
else idx = (idx - 1 >= 0 ? idx - 1 : 3) % 4;
}
}
int tmp = front;
back = preset[front][back][idx];
up = tmp;
front = 7 - back;
}
cout << ans;
}
This post is licensed under CC BY 4.0 by the author.