백준 Gold 4 주사위 굴리기
주사위 굴리기 (백준 Gold 4)
https://www.acmicpc.net/problem/14499
모든 면이 0인 주사위가 주어지고
특정한 맵 데이터가 주어질 때,
각 움직임마다, 주사위의 ‘위쪽’ 숫자를 출력하는 문제
조건
- x(0~n-1), y(0~m-1)이 주어짐
- 명령은 동서북남 순으로 1234 가 매핑됨
- 주사위가 움직일때의 추가 조건들
- 주사위가 이동한 후, 위쪽의 숫자가 출력됨
다만, 이동이 불가능한 위치의 명령이 주어진 경우는
명령과 출력이 무시됨 - 주사위가
이동한 칸
에 쓰여있는 수가 0이라면,
바닥값이 해당 위치에 복사됨
(주사위 -> 맵) - 0이 아닌 경우, 주사위의 바닥면으로 복사되고
해당 칸의 값이 0이됨
(맵 -> 주사위)
- 주사위가 이동한 후, 위쪽의 숫자가 출력됨
- 주사위가 시작하는 위치의 값은 0
풀이 방법
나는 주사위에 관련된 클래스를 제작하여 문제를 풀었다
유의할 점은
'이동 성공 판정'
- 방향에 따른 주사위 각 면의 값 교환
이며,
각 방향에 따라 4개의 면의 값들을 수정해주었다
제출 코드
#include<iostream>
#include<vector>
using namespace std;
enum dir
{
d_Right = 0,
d_Left,
d_Up,
d_Down,
};
int dirY[4] = { 0,0,-1,1 };
int dirX[4] = { 1,-1,0,0 };
int n, m, x, y, k;
class dice
{
public:
dice(int nowY, int nowX)
{
nowPosY = nowY;
nowPosX = nowX;
}
int GetTop() const { return top; }
bool Roll(vector<vector<int>>& maps, dir d)
{
int di = static_cast<int>(d);
int ny = nowPosY + dirY[di];
int nx = nowPosX + dirX[di];
if (ny < 0 || ny >= n ||
nx < 0 || nx >= m)
return false;
// 원본 값들
int otop = top;
int odown = down;
int oright = right;
int oleft = left;
int oforward = forward;
int oback = back;
switch (d)
{
case d_Right: {
top = oleft;
right = otop;
down = oright;
left = odown;
}
break;
case d_Left: {
top = oright;
left = otop;
down = oleft;
right = odown;
}
break;
case d_Up: {
top = oback;
back = odown;
down = oforward;
forward = otop;
}
break;
case d_Down: {
top = oforward;
forward = odown;
down = oback;
back = otop;
}
break;
}
if (maps[ny][nx] != 0)
{
down = maps[ny][nx];
maps[ny][nx] = 0;
}
else
{
maps[ny][nx] = down;
}
nowPosY = ny;
nowPosX = nx;
return true;
}
protected:
int nowPosY, nowPosX;
int top = 0;
int down = 0;
int right = 0;
int left = 0;
int forward = 0;
int back = 0;
};
int main()
{
cin >> n >> m >> y >> x >> k;
vector<vector<int>> maps(n, vector<int>(m, 0));
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> maps[i][j];
dice dic(y, x);
for (int i = 0; i < k; i++)
{
int ord;
cin >> ord;
ord--;
if (dic.Roll(maps, static_cast<dir>(ord)))
{
cout << dic.GetTop() << '\n';
}
}
return 0;
}
결과
틀린 부분은 문제의 조건 중
‘이동한 칸에 쓰여 있는 수가 0이면, 주사위의 바닥면에 쓰여 있는 수가 칸에 복사된다’
부분을 구현하지 못하여 틀렸었다
문제를 잘 읽어야 한다…
댓글남기기