[BOJ] 14499번 : 주사위 굴리기
2024. 8. 22. 00:58ㆍAlgorithm
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 |