티스토리 뷰
728x90
문제
오늘은 2×2×2 루빅스 큐브를 풀어보려고 한다. 큐브의 각 면은 양방향으로 90도 돌릴 수 있게 만들어져 있다. 큐브의 각 면에 있는 색상이 모두 같으면 큐브를 풀었다고 한다.
2×2×2 루빅스 큐브가 주어졌을 때, 정확히 한 번 돌려서 큐브를 풀 수 있는지 아닌지 구해보자.
입력
첫째 줄에 2×2×2 루빅스 큐브 각 면의 각 칸 색상이 주어진다. 색상은 1부터 6까지의 자연수로 나타내며, 각 자연수는 총 4번 등장한다. i번째 수가 의미하는 칸은 아래와 같다.
출력
루빅스 큐브를 정확히 한 번 돌려서 풀 수 있으면 1, 없으면 0을 출력한다.
코드
#include <iostream>
#define TOP 0
#define FRONT 1
#define BOTTOM 2
#define LEFT 3
#define RIGHT 4
#define BACK 5
using namespace std;
int cube[24];
bool surface[6];
// 각 면의 모든 칸이 같은 색인지 확인
void check()
{
int i, j, color;
bool same;
for (i = 0; i < 6; i++)
{
color = cube[4 * i];
same = true;
for (j = 1; j < 4; j++)
{
if (cube[4 * i + j] != color)
{
same = false;
break;
}
}
surface[i] = same;
}
}
// 주어진 두 칸의 색이 같은지 확인
bool check_color(int sur1, int a, int sur2, int b)
{
if (cube[sur1 * 4 + a] == cube[sur2 * 4 + b])
return true;
return false;
}
// TOP과 BOTTOM이 같은 경우
bool same_TB()
{
int i;
int arr[] = {3, 1, 4, 5};
bool res;
// 정방향으로 돌리는 경우 풀 수 있는지 확인
res = true;
for (i = 0; i < 3; i++)
{
if (!check_color(arr[i], 0, arr[i], 1) || !check_color(arr[i + 1], 2, arr[i + 1], 3) || !check_color(arr[i], 0, arr[i + 1], 2))
{
res = false;
break;
}
}
// 풀 수 있으면 리턴
if (res)
{
return res;
}
// 역뱡향으로 돌리는 경우 풀 수 있는지 확인
res = true;
for (i = 0; i < 3; i++)
{
if (!check_color(arr[i], 2, arr[i], 3) || !check_color(arr[i + 1], 0, arr[i + 1], 1) || !check_color(arr[i], 2, arr[i + 1], 0))
{
res = false;
break;
}
}
return res;
}
// FRONT와 BACK이 같은 경우
bool same_FB()
{
int arr[] = {0, 3, 2, 4};
bool res;
// 정방향으로 돌리는 경우 풀 수 있는지 확인
res = true;
if (!check_color(arr[0], 2, arr[0], 3) || !check_color(arr[1], 0, arr[1], 2) || !check_color(arr[0], 2, arr[1], 0))
{
res = false;
}
else if (!check_color(arr[1], 1, arr[1], 3) || !check_color(arr[2], 2, arr[2], 3) || !check_color(arr[1], 1, arr[2], 2))
{
res = false;
}
else if (!check_color(arr[2], 0, arr[2], 1) || !check_color(arr[3], 1, arr[3], 3) || !check_color(arr[2], 0, arr[3], 1))
{
res = false;
}
// 풀 수 있으면 리턴
if (res)
{
return res;
}
// 역뱡향으로 돌리는 경우 풀 수 있는지 확인
res = true;
if (!check_color(arr[0], 0, arr[0], 1) || !check_color(arr[1], 1, arr[1], 3) || !check_color(arr[0], 0, arr[1], 1))
{
res = false;
}
else if (!check_color(arr[1], 0, arr[1], 2) || !check_color(arr[2], 0, arr[2], 1) || !check_color(arr[1], 0, arr[2], 0))
{
res = false;
}
else if (!check_color(arr[2], 2, arr[2], 3) || !check_color(arr[3], 0, arr[3], 2) || !check_color(arr[2], 2, arr[3], 0))
{
res = false;
}
return res;
}
// LEFT와 RIGHT가 같은 경우
bool same_LR()
{
int i;
int arr[] = {0, 1, 2, 5};
bool res;
// 정방향으로 돌리는 경우 풀 수 있는지 확인
res = true;
for (i = 0; i < 2; i++)
{
if (!check_color(arr[i], 0, arr[i], 2) || !check_color(arr[i + 1], 1, arr[i + 1], 3) || !check_color(arr[i], 0, arr[i + 1], 1))
{
res = false;
}
}
if ((!check_color(arr[i], 0, arr[i], 2) || !check_color(arr[i + 1], 0, arr[i + 1], 2) || !check_color(arr[i], 0, arr[i + 1], 0)))
{
res = false;
}
// 풀 수 있으면 리턴
if (res)
{
return res;
}
// 역뱡향으로 돌리는 경우 풀 수 있는지 확인
res = true;
for (i = 0; i < 2; i++)
{
if (!check_color(arr[i], 1, arr[i], 3) || !check_color(arr[i + 1], 0, arr[i + 1], 2) || !check_color(arr[i], 1, arr[i + 1], 0))
{
res = false;
}
}
if ((!check_color(arr[i], 1, arr[i], 3) || !check_color(arr[i + 1], 1, arr[i + 1], 3) || !check_color(arr[i], 1, arr[i + 1], 1)))
{
res = false;
}
return res;
}
int main()
{
int i;
bool res = false;
for (i = 0; i < 24; i++)
{
cin >> cube[i];
}
check();
if (surface[TOP] && surface[BOTTOM])
{
if (same_TB())
{
res = true;
}
}
else if (surface[FRONT] && surface[BACK])
{
if (same_FB())
{
res = true;
}
}
else if (surface[LEFT] && surface[RIGHT])
{
if (same_LR())
{
res = true;
}
}
cout << res << endl;
return 0;
}
큐브의 각 칸에 주어진 수에 따라 다음과 같이 각 면에 번호를 부여했다. 같은 색으로 칠해진 두 면은 서로 마주 보는 면이다.
루빅스 큐브를 정확히 한 번 돌려서 풀 수 있는 경우는 다음의 6가지 밖에 없다. 한 쌍의 마주보는 면이 같은 색으로 맞춰져 있고, 나머지 면들은 돌리는 방향에 따라 인접한 두 칸이 같은 색이어야 한다. 이 경우 화살표 방향으로 큐브를 돌려 풀 수 있다.
링크
728x90
'Coding Test > Baekjoon' 카테고리의 다른 글
[백준] 16954번 - 움직이는 미로 탈출 / C++ (0) | 2021.03.10 |
---|---|
[백준] 16933번 - 벽 부수고 이동하기 3 / C++ (0) | 2021.03.08 |
[백준] 16974번 - 레벨 햄버거 / C++ (0) | 2021.02.27 |
[백준] 14442번 - 벽 부수고 이동하기 2 / C++ (0) | 2021.02.27 |
[백준] 16946번 - 벽 부수고 이동하기 4 / C++ (0) | 2021.02.27 |