[Baekjoon,14499]주사위 굴리기
해결
너무 복잡하게 생각하면 안되는 문제이다. 우아한 코드를 작성하려고 어렵게 접근하면 더 어려워진다. 초기에는 어렵게 객체로 주사위를 표현하여 해결하려 했으나 실패했다.
전개도를 최신화
간단한 해결 방법은 주사위를 굴릴 때 마다 전개도를 최신화 한다고 생각하는 것이다. 예를 들어 현재 1이 가장 위에 있고 동쪽에 3이 위치한 주사위 전개도가 아래와 같다고 해보자.
2
4 1 3
5
6
여기서 주사위를 아래로 굴리는 경우 아래와 같이 변경된다.
6
4 2 3
1
5
이번에는 오른쪽으로 굴려보자.
6
5 4 2
1
3
위와 같이 변경되는 부분을 방향에 따라 아래와 같이 코드를 작성하면 된다.
enum{ RIGHT=1, LEFT, UP, DOWN };
// index: 0,1,2,3,4,5
int dice[6]={0,0,0,0,0,0};
// 주사위를 굴릴 때 마다 전개도를 update한다.
void update(int dir)
{
int temp=dice[0];
switch(dir)
{
case RIGHT:
dice[0]=dice[3];
dice[3]=dice[5];
dice[5]=dice[2];
dice[2]=temp;
break;
case LEFT:
dice[0]=dice[2];
dice[2]=dice[5];
dice[5]=dice[3];
dice[3]=temp;
break;
case UP:
dice[0]=dice[4];
dice[4]=dice[5];
dice[5]=dice[1];
dice[1]=temp;
break;
case DOWN:
dice[0]=dice[1];
dice[1]=dice[5];
dice[5]=dice[4];
dice[4]=temp;
break;
}
}
구현
구현 시 주의할 점은 주사위의 x,y 좌표가 입력될 때 y값이 먼저 입력되기 때문에 cin>>y>>x
순으로 입력받아야 한다.
#include <iostream>
#include <vector>
using namespace std;
const int dy[4]={0,0,-1,1};
const int dx[4]={1,-1,0,0};
enum{ RIGHT=1, LEFT, UP, DOWN };
int H,W;
int map[20][20];
// index: 0,1,2,3,4,5
int dice[6]={0,0,0,0,0,0};
inline bool inRange(int y, int x)
{
return 0<=y && y<H && 0<=x && x<W;
}
// 주사위를 굴릴 때 마다 전개도를 update한다.
void update(int dir)
{
int temp=dice[0];
switch(dir)
{
case RIGHT:
dice[0]=dice[3];
dice[3]=dice[5];
dice[5]=dice[2];
dice[2]=temp;
break;
case LEFT:
dice[0]=dice[2];
dice[2]=dice[5];
dice[5]=dice[3];
dice[3]=temp;
break;
case UP:
dice[0]=dice[4];
dice[4]=dice[5];
dice[5]=dice[1];
dice[1]=temp;
break;
case DOWN:
dice[0]=dice[1];
dice[1]=dice[5];
dice[5]=dice[4];
dice[4]=temp;
break;
}
}
int main()
{
cin>>H>>W;
int y,x,k;
cin>>y>>x>>k;
for(int i=0;i<H;++i)
for(int j=0;j<W;++j)
cin>>map[i][j];
while(k--)
{
int dir;
cin>>dir;
// 맵에서 주사위의 다음 위치
int ny=y+dy[dir-1];
int nx=x+dx[dir-1];
// 범위 확인
if(!inRange(ny,nx))
continue;
// 주사위를 굴린다.
update(dir);
cout<<dice[0]<<endl;
if(map[ny][nx]==0)
map[ny][nx]=dice[5];
else
{
dice[5]=map[ny][nx];
map[ny][nx]=0;
}
y=ny;
x=nx;
}
return 0;
}
댓글남기기