[백준] 14499: 주사위 굴리기(with C++)
주사위 굴리기 주사기 굴리위 주사리 굴위기
어떻게 풀었는지 모르겠다. 40분 남았길래 허겁지겁 읽고 후다닥 풀었다.
다행히 아주 나이스한 문제였다. 그냥 구현, 시뮬레이션 문제였다. 본인이 헷갈리지 않게 짜는게 중요한 듯 하다. 아 그리고 저번 포스팅에서 말했듯이 나는 x,y좌표가 필요할 때는 항상 원점을 왼쪽 상단으로 두고 가로를 y축, 세로를 x축으로 생각하면서 푸는데 마침 이 문제 조건도 그렇게 나왔다. 정말 운이 좋았다.
참고로 내가 뭔 대회를 나갔다가 왔다거나 한 건 아니다. 그냥 세시간 재놓고 두문제 푸는 연습 중이다.
문제
크기가 N×M인 지도가 존재한다. 지도의 오른쪽은 동쪽, 위쪽은 북쪽이다. 이 지도의 위에 주사위가 하나 놓여져 있으며, 주사위의 전개도는 아래와 같다. 지도의 좌표는 (r, c)로 나타내며, r는 북쪽으로부터 떨어진 칸의 개수, c는 서쪽으로부터 떨어진 칸의 개수이다.
2
4 1 3
5
6
주사위는 지도 위에 윗 면이 1이고, 동쪽을 바라보는 방향이 3인 상태로 놓여져 있으며, 놓여져 있는 곳의 좌표는 (x, y) 이다. 가장 처음에 주사위에는 모든 면에 0이 적혀져 있다.
지도의 각 칸에는 정수가 하나씩 쓰여져 있다. 주사위를 굴렸을 때, 이동한 칸에 쓰여 있는 수가 0이면, 주사위의 바닥면에 쓰여 있는 수가 칸에 복사된다. 0이 아닌 경우에는 칸에 쓰여 있는 수가 주사위의 바닥면으로 복사되며, 칸에 쓰여 있는 수는 0이 된다.
주사위를 놓은 곳의 좌표와 이동시키는 명령이 주어졌을 때, 주사위가 이동했을 때 마다 상단에 쓰여 있는 값을 구하는 프로그램을 작성하시오.
주사위는 지도의 바깥으로 이동시킬 수 없다. 만약 바깥으로 이동시키려고 하는 경우에는 해당 명령을 무시해야 하며, 출력도 하면 안 된다.
https://www.acmicpc.net/problem/14499
14499번: 주사위 굴리기
첫째 줄에 지도의 세로 크기 N, 가로 크기 M (1 ≤ N, M ≤ 20), 주사위를 놓은 곳의 좌표 x, y(0 ≤ x ≤ N-1, 0 ≤ y ≤ M-1), 그리고 명령의 개수 K (1 ≤ K ≤ 1,000)가 주어진다. 둘째 줄부터 N개의 줄에 지
www.acmicpc.net
구상
와 메모를 봤는데 진짜 참고가 안된다. ㅋㅋㅋㅋ
[아이디어]
1. 주사위의 정보(위치와 각 면에 쓰인 숫자)를 저장하는 struct를 선언한다.
1) 위치는 2차원 배열로 0번에 x좌표, 1번에 y좌표를 쓴다.
2) 숫자는 전개도대로 0~5 배열에 쓴다.
2. 주사위를 굴리는 함수를 따로 짠다.
1) 먼저 x,y 값을 이동한다. invalid한 이동이면 그냥 이전 주사위 그대로 리턴한다.
2) 다음으로 숫자값을 이동한다. 설명하기 어렵지만, 주사위는 초기 모양(1이 윗면, 3이 동쪽면) 그대로 있다고 생각하고 적혀있는 숫자를 이동해서 주사위를 굴린 듯한 효과를 줬다.
3) 만약 변화한 주사위 좌표값에 대응하는 맵의 위치가 0이면 주사위 밑면((2)처럼 풀면 인덱스 5로 고정이다)에 쓰인 숫자를 적고, 아니면 주사위 밑면에 그 숫자를 넣고 맵 위치 그 칸은 0으로 만든다.
3. 명령대로 주사위를 굴린다.
이번에는 설명을 좀 잘한 것 같다. 코드는 아래와 같다.
#include<iostream>
using namespace std;
struct Dice {
int place[2];
int numbers[6];
};
Dice move(int command, int** map, Dice dice, int N, int M) {
Dice result;
int x = dice.place[0];
int y = dice.place[1];
if(command == 1) {
//right
if(y == M-1) {
return dice;
}
else {
result.place[0] = x;
result.place[1] = y + 1;
}
result.numbers[0] = dice.numbers[3];
result.numbers[1] = dice.numbers[1];
result.numbers[2] = dice.numbers[0];
result.numbers[3] = dice.numbers[5];
result.numbers[4] = dice.numbers[4];
result.numbers[5] = dice.numbers[2];
if(map[result.place[0]][result.place[1]] == 0) {
map[result.place[0]][result.place[1]] = result.numbers[5];
}
else {
result.numbers[5] = map[result.place[0]][result.place[1]];
map[result.place[0]][result.place[1]] = 0;
}
}
else if(command == 2) {
//left
if(y == 0) {
return dice;
}
else {
result.place[0] = x;
result.place[1] = y - 1;
}
result.numbers[0] = dice.numbers[2];
result.numbers[1] = dice.numbers[1];
result.numbers[2] = dice.numbers[5];
result.numbers[3] = dice.numbers[0];
result.numbers[4] = dice.numbers[4];
result.numbers[5] = dice.numbers[3];
if(map[result.place[0]][result.place[1]] == 0) {
map[result.place[0]][result.place[1]] = result.numbers[5];
}
else {
result.numbers[5] = map[result.place[0]][result.place[1]];
map[result.place[0]][result.place[1]] = 0;
}
}
else if(command == 3) {
//up
if(x == 0) {
return dice;
}
else {
result.place[0] = x - 1;
result.place[1] = y;
}
result.numbers[0] = dice.numbers[4];
result.numbers[1] = dice.numbers[0];
result.numbers[2] = dice.numbers[2];
result.numbers[3] = dice.numbers[3];
result.numbers[4] = dice.numbers[5];
result.numbers[5] = dice.numbers[1];
if(map[result.place[0]][result.place[1]] == 0) {
map[result.place[0]][result.place[1]] = result.numbers[5];
}
else {
result.numbers[5] = map[result.place[0]][result.place[1]];
map[result.place[0]][result.place[1]] = 0;
}
}
else {
//down
if(x == N-1) {
return dice;
}
else {
result.place[0] = x + 1;
result.place[1] = y;
}
result.numbers[0] = dice.numbers[1];
result.numbers[1] = dice.numbers[5];
result.numbers[2] = dice.numbers[2];
result.numbers[3] = dice.numbers[3];
result.numbers[4] = dice.numbers[0];
result.numbers[5] = dice.numbers[4];
if(map[result.place[0]][result.place[1]] == 0) {
map[result.place[0]][result.place[1]] = result.numbers[5];
}
else {
result.numbers[5] = map[result.place[0]][result.place[1]];
map[result.place[0]][result.place[1]] = 0;
}
}
return result;
}
int main(int argc, char** argv)
{
ios_base :: sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int N, M, x, y, K;
int** map;
cin >> N >> M >> x >> y >> K;
map = new int*[N];
for(int i=0; i<N; i++) {
map[i] = new int[M];
for(int j=0; j<M; j++) {
cin >> map[i][j];
}
}
Dice dice;
dice.place[0] = x;
dice.place[1] = y;
for(int i= 0; i<6; i++) {
dice.numbers[i] = 0;
}
for(int i=0; i<K; i++) {
int command;
cin >> command;
Dice new_dice = move(command, map, dice, N, M);
if(new_dice.place[0] == dice.place[0] && new_dice.place[1] == dice.place[1]) {
continue;
}
else {
cout << new_dice.numbers[0] << "\n";
dice = new_dice;
}
}
return 0;
}