[BOJ] 14499번 : 주사위 굴리기

2024. 8. 22. 00:58Algorithm

1. problem : 

https://www.acmicpc.net/problem/14499

 

2. solution 1 :

#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
int n, m, x, y, k; 
int board[24][24]; 
int dice[8]; // 원본 순서저장 ;
int dice2[8]; // 복사본 순서저장 ;
//명령은 반복문 안에서 받자. 
void change_dice(int dir) {
	if (dir == 1) {
		dice2[0] = dice[2];
		dice2[1] = dice[1];
		dice2[2] = dice[5];
		dice2[3] = dice[0];
		dice2[4] = dice[4];
		dice2[5] = dice[3];
		for (int i = 0; i < 6; i++) dice[i] = dice2[i];
	}
	if (dir == 2) {
		dice2[0] = dice[3];
		dice2[1] = dice[1];
		dice2[2] = dice[0];
		dice2[3] = dice[5];
		dice2[4] = dice[4];
		dice2[5] = dice[2];
		for (int i = 0; i < 6; i++) dice[i] = dice2[i];
	}
	if (dir == 3) {
		dice2[0] = dice[1];
		dice2[1] = dice[5];
		dice2[2] = dice[2];
		dice2[3] = dice[3];
		dice2[4] = dice[0];
		dice2[5] = dice[4];
		for (int i = 0; i < 6; i++) dice[i] = dice2[i];
	}
	if (dir == 4) {
		dice2[0] = dice[4];
		dice2[1] = dice[0];
		dice2[2] = dice[2];
		dice2[3] = dice[3];
		dice2[4] = dice[5];
		dice2[5] = dice[1];
		for (int i = 0; i < 6; i++) dice[i] = dice2[i];
	}
}
int main(void) {
	ios::sync_with_stdio(0);
	cin.tie(0); 
	cin >> n >> m >> x >> y >> k; 
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) cin >> board[i][j];
	}
	
	pair<int, int> cur = { x,y };
	while (k--) {
		int way;
		cin >> way; 
		if (way == 1) {
			if (cur.Y < m -1) {
				change_dice(1);
				cur = { cur.X,cur.Y +1 }; //current위치 바꾸기 
				if (board[cur.X][cur.Y] != 0) {
					dice[0] = board[cur.X][cur.Y];
					board[cur.X][cur.Y] = 0;
				}
				else board[cur.X][cur.Y] = dice[0];
				cout << dice[5] << '\n';
			}
		}
		if (way == 2) {
			if (cur.Y  > 0) {
				change_dice(2);
				cur = { cur.X,cur.Y - 1 }; //current위치 바꾸기 
				if (board[cur.X][cur.Y] != 0) {
					dice[0] = board[cur.X][cur.Y];
					board[cur.X][cur.Y] = 0;
				}
				else board[cur.X][cur.Y] = dice[0];
				cout << dice[5] << '\n';
			}
		}
		if (way == 3) {
			if (cur.X > 0) {
				change_dice(3);
				cur = { cur.X - 1,cur.Y }; //current위치 바꾸기 
				if (board[cur.X][cur.Y] != 0) {
					dice[0] = board[cur.X][cur.Y];
					board[cur.X][cur.Y] = 0;
				}
				else board[cur.X][cur.Y] = dice[0];
				cout << dice[5] << '\n';
			}
		}
		if (way == 4) {
			if (cur.X < n-1) {
				change_dice(4);
				cur = { cur.X + 1,cur.Y }; //current위치 바꾸기 
				if (board[cur.X][cur.Y] != 0) {
					dice[0] = board[cur.X][cur.Y];
					board[cur.X][cur.Y] = 0;
				}
				else board[cur.X][cur.Y] = dice[0];
				cout << dice[5] << '\n';
			}
		}
	}
}

 

3. solution 2 :

#include <bits/stdc++.h>
using namespace std;

#define X first
#define Y second
int n, m, x, y, k; 
int board[24][24]; 
int dice[6]; // 주사위의 각 면을 나타내는 배열

void change_dice(int dir) {
    int temp[6];
    for (int i = 0; i < 6; i++) temp[i] = dice[i];
    if (dir == 1) { // 동쪽
        dice[0] = temp[3];
        dice[2] = temp[0];
        dice[3] = temp[5];
        dice[5] = temp[2];
    } else if (dir == 2) { // 서쪽
        dice[0] = temp[2];
        dice[2] = temp[5];
        dice[3] = temp[0];
        dice[5] = temp[3];
    } else if (dir == 3) { // 북쪽
        dice[0] = temp[4];
        dice[1] = temp[0];
        dice[4] = temp[5];
        dice[5] = temp[1];
    } else if (dir == 4) { // 남쪽
        dice[0] = temp[1];
        dice[1] = temp[5];
        dice[4] = temp[0];
        dice[5] = temp[4];
    }
}

int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0);
    
    cin >> n >> m >> x >> y >> k;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) cin >> board[i][j];
    }
    
    pair<int, int> cur = {x, y};
    
    while (k--) {
        int way;
        cin >> way;
        int nx = cur.X, ny = cur.Y;
        
        if (way == 1) ny += 1; // 동쪽
        if (way == 2) ny -= 1; // 서쪽
        if (way == 3) nx -= 1; // 북쪽
        if (way == 4) nx += 1; // 남쪽
        
        // 경계를 벗어나는 경우 무시
        if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
        
        // 주사위 위치 갱신
        cur = {nx, ny};
        change_dice(way);
        
        // 주사위 바닥과 보드의 값 갱신
        if (board[nx][ny] == 0) {
            board[nx][ny] = dice[0]; // 주사위 바닥면의 값 복사
        } else {
            dice[0] = board[nx][ny]; // 보드의 값을 주사위 바닥면에 복사
            board[nx][ny] = 0;       // 보드의 값은 0으로 변경
        }
        
        // 주사위 윗면의 값 출력
        cout << dice[5] << '\n';
    }
}

solution 1를 다듬은 버전, chatgpt가 짜줌 

 

4. solution 3 :

// Authored by : OceanShape
// Co-authored by : BaaaaaaaaaaarkingDog
// http://boj.kr/f4d1f744e8284036b39106a41f13ffe2
#include <bits/stdc++.h>
using namespace std;

int N, M, x, y, K, command;
int board[21][21];  // 지도
int dice[7];        // 주사위
//  윗면이 2이고, 동쪽을 바라보는 방향이 6
//     [1]
//  [5][2][6]
//     [3]
//     [4]

int idx[5][4] = {
  {},        // dummy
  {2,6,4,5}, // 동쪽, 5->2, 2->6, 6->4, 4->5
  {2,5,4,6}, // 서쪽, 6->2, 2->5, 5->4, 4->6
  {3,2,1,4}, // 북쪽, 4->3, 3->2, 2->1, 1->4
  {2,3,4,1}, // 남쪽, 1->2, 2->3, 3->4, 4->1
};

// 명령어가 유효한지 검증하는 함수
bool isOk(int nx, int ny){
  if(nx<0||nx>=N||ny<0||ny>=M) return false;
  return true;
}

// 주사위를 굴리는 함수
void roll(int com){
  // 회전 시 기존 주사위의 값을 별도로 보존하기 위한 배열 생성
  int tmp[7];
  for(int i = 1; i <= 6; ++i) tmp[i]=dice[i];

  // 굴리는거 처리
  for(int i = 0; i < 4; i++)
    tmp[idx[com][i]] = dice[idx[com][(i+1)%4]];

  // 회전 결괏값을 기존 주사위에 대입
  for(int i = 1; i <= 6; ++i) dice[i]=tmp[i];
}

void score(int c){
  int nx=x, ny=y;
  // 주사위 위치 이동
  if(c==1) ++ny;
  else if(c==2) --ny;
  else if(c==3) --nx;
  else ++nx;

  if(isOk(nx, ny)){
    x=nx; y=ny; // 유효성 확인 후 주사위의 위치 대입
    roll(c);
    // 0일 경우
    if(board[nx][ny]==0)
      board[nx][ny]=dice[4]; // 칸에 바닥면 값 대입
    
    // 0이 아닐 경우
    else {
      dice[4]=board[nx][ny]; // 바닥면에 칸 값 대입
      board[nx][ny]=0; // 칸 값을 0으로 초기화
    }
    cout << dice[2] << '\n'; // 주사위 윗면 출력
  }
}

int main(void){
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> N >> M >> x >> y >> K;
  for(int i = 0; i < N; ++i)
    for(int j = 0; j < M; ++j)
      cin >> board[i][j];

  while(K--){
    cin >> command;
    score(command);
  }
}

source code 출처 : https://github.com/encrypted-def/basic-algo-lecture/blob/master/0x0D/solutions/14499.cpp#L9

'Algorithm' 카테고리의 다른 글

[BOJ] 16985번 : Maaaaaaaaaze  (0) 2024.08.22
[BOJ] 13335번 : 트럭  (0) 2024.08.22
[BOJ] 14891번 : 톱니바퀴  (0) 2024.08.21
[BOJ] 11559번 : Puyo Puyo  (0) 2024.08.21
[BOJ] 15686번 : 치킨 배달  (0) 2024.08.20