BOJ 11742 Hypercube
sorohue가 PS하는 블로그
BOJ 11742 Hypercube
문제 링크입니다.
문제 요약
주어진 정팔포체의 전개도가 올바른지 판별합시다.
정육면체의 전개도로부터의 확장
정육면체의 전개도를 그리라 하면 저는 보통 이런 그림을 그립니다. 이 전개도를 접으면, 위아래의 면이 3, 4고 이를 둘러싸는 옆면이 1, 5, 6, 2인 육면체 주사위를 얻을 수 있습니다.
여기서, 옆면을 이루는 1, 5, 6, 2가 전개도 상에서 한 줄을 이루고 있음에 주목합시다. 이 줄은 접는 과정에서 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
48
49
50
51
52
53
54
55
56
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
char board[10][10][10];
bool vis[10][10][10];
int now[7][7][7];
int n, m, k;
set<int> st;
const int dx[] = {1,-1,0,0,0,0};
const int dy[] = {0,0,1,-1,0,0};
const int dz[] = {0,0,0,0,1,-1};
void solve(int x, int y, int z){
st.insert(now[3][3][3]);
vis[x][y][z] = 1;
for(int d = 0; d < 6; d++){
if(board[x+dx[d]][y+dy[d]][z+dz[d]] == '.') continue;
if(vis[x+dx[d]][y+dy[d]][z+dz[d]]) continue;
for(int i = 2; i >= -1; i--) now[3+i*dx[d]][3+i*dy[d]][3+i*dz[d]] = now[3+(i-1)*dx[d]][3+(i-1)*dy[d]][3+(i-1)*dz[d]];
now[1][3][3] = now[5][3][3] = 9-now[3][3][3];
now[3][1][3] = now[3][5][3] = 9-now[3][3][3];
now[3][3][1] = now[3][3][5] = 9-now[3][3][3];
solve(x+dx[d], y+dy[d], z+dz[d]);
for(int i = 2; i >= -1; i--) now[3+i*dx[d^1]][3+i*dy[d^1]][3+i*dz[d^1]] = now[3+(i-1)*dx[d^1]][3+(i-1)*dy[d^1]][3+(i-1)*dz[d^1]];
now[1][3][3] = now[5][3][3] = 9-now[3][3][3];
now[3][1][3] = now[3][5][3] = 9-now[3][3][3];
now[3][3][1] = now[3][3][5] = 9-now[3][3][3];
}
}
int main(){
cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
memset(board, '.', sizeof(board));
cin >> m >> n >> k;
int sx, sy, sz;
for(int z = 1; z <= k; z++) for(int y = 1; y <= n; y++) for(int x = 1; x <= m; x++){
cin >> board[x][y][z];
if(board[x][y][z] == 'x'){sx = x; sy = y; sz = z;}
}
now[3][3][3] = 1;
now[4][3][3] = 2;
now[3][4][3] = 3;
now[3][3][4] = 4;
now[3][3][2] = 5;
now[3][2][3] = 6;
now[2][3][3] = 7;
now[1][3][3] = now[5][3][3] = 8;
now[3][1][3] = now[3][5][3] = 8;
now[3][3][1] = now[3][3][5] = 8;
solve(sx, sy, sz);
cout << (st.size() == 8 ? "Yes" : "No");
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

