[Baekjoon,14499]주사위 굴리기

1 분 소요

해결

너무 복잡하게 생각하면 안되는 문제이다. 우아한 코드를 작성하려고 어렵게 접근하면 더 어려워진다. 초기에는 어렵게 객체로 주사위를 표현하여 해결하려 했으나 실패했다.

전개도를 최신화

간단한 해결 방법은 주사위를 굴릴 때 마다 전개도를 최신화 한다고 생각하는 것이다. 예를 들어 현재 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;
}

댓글남기기