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
풀이
이 문제에서 가장 까다로웠던 것은 주사위가 굴러가는 것이다. 좌, 우로만 움직이거나 상, 하로만 움직인다면 굉장히 쉬운 일이지만 만약 지금 상태에서 상하로 구르는 것과 좌로 한 칸 이동 후에 상하로 구르는 것은 완전 다른 패턴을 가지고 있으므로 표현하는 것이 어렵다. 따라서 주사위가 상,하,좌,우로 굴렀을 때 값의 위치가 어디로 가는 지를 알고 상, 하, 좌, 우로 이동하는 함수 4개를 만들었다. 예시로 다음과 같다. 만약 주사위가 위의 문제와 같이 있고 1이 위에 있다고 가정하자. 주사위를 위로 굴렸을 때 값은 이렇게 바뀐다.
1번 자리 : 5
2번 자리 : 1
3번 자리 : 3
4번 자리 : 4
5번 자리 : 6
6번 자리 : 2
이런 방식으로 상, 하, 좌, 우로 굴렀을 때의 주사위를 나타내는 함수를 만들었다. 그 다음은 어렵지 않다. 문제에서 준 대로 바닥이 0인 경우 주사위의 아래있는 값을 복사하고 0이 아닌 경우 주사위의 면을 갱신하고 바닥을 0으로 만들면 된다.
소스 코드
#include <iostream>
#include <cstring>
#include <vector>
#include <deque>
using namespace std;
int board[21][21];
int dice[6] = {0, 0, 0, 0, 0, 0}; //초기 주사위 전개도 순서로 초기화
void up() { //위로 굴렀을 때의 주사위 값 변화
int tmp[6];
tmp[0] = dice[4];
tmp[1] = dice[0];
tmp[2] = dice[2];
tmp[3] = dice[3];
tmp[4] = dice[5];
tmp[5] = dice[1];
memcpy(dice, tmp, sizeof(dice));
}
void down() { //아래로 굴렀을 때의 주사위 값 변화
int tmp[6];
tmp[0] = dice[1];
tmp[1] = dice[5];
tmp[2] = dice[2];
tmp[3] = dice[3];
tmp[4] = dice[0];
tmp[5] = dice[4];
memcpy(dice, tmp, sizeof(dice));
}
void left() { //왼쪽으로 굴렀을 때의 주사위 값 변화
int tmp[6];
tmp[0] = dice[2];
tmp[1] = dice[1];
tmp[2] = dice[5];
tmp[3] = dice[0];
tmp[4] = dice[4];
tmp[5] = dice[3];
memcpy(dice, tmp, sizeof(dice));
}
void right() { //오른쪽으로 굴렀을 때의 주사위 값 변화
int tmp[6];
tmp[0] = dice[3];
tmp[1] = dice[1];
tmp[2] = dice[0];
tmp[3] = dice[5];
tmp[4] = dice[4];
tmp[5] = dice[2];
memcpy(dice, tmp, sizeof(dice));
}
int main() {
int N, M, x, y, K; cin >> N >> M >> x >> y >> K;
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
cin >> board[i][j];
}
}
if(board[x][y] == 0) { //바닥이 0인 경우
board[x][y] = dice[5]; //주사위값 복사
}
else { //바닥이 0이 아닌 경우
dice[5] = board[x][y]; //주사위에 바닥값 복사
board[x][y] = 0; //바닥은 0으로
}
for(int i = 0; i < K; i++) {
int a; cin >> a;
switch(a) {
case 1: //동쪽으로 가는 경우
if(y + 1 < M) { //벗어나지 않을 때 동작
y++;
right();
}
else continue;
break;
case 2: //서쪽으로 가는 경우
if(y-1 >= 0) {
y--;
left();
}
else continue;
break;
case 3: //북쪽으로 가는 경우
if(x-1 >= 0) {
x--;
up();
}
else continue;
break;
case 4: //남쪽으로 가는 경우
if(x+1 < N) {
x++;
down();
}
else continue;
break;
}
if(board[x][y] == 0) { //바닥이 0인 경우
board[x][y] = dice[5]; //바닥에 주사위 아래값 복사
}
else { //바닥이 1인 경우
dice[5] = board[x][y]; //주사위 아래에 바닥값 복사
board[x][y] = 0; //바닥은 0으로
}
cout << dice[0] << '\n'; //주사위 위에 있는 값 출력
}
}
채점 결과
'알고리즘 > 백준' 카테고리의 다른 글
[C++] 백준 5502번 펠린드롬 풀이 (0) | 2021.08.24 |
---|---|
[C++] 백준 9251번 LCS 풀이 (0) | 2021.08.24 |
[C++] 백준 13458번 시험 감독 풀이 (0) | 2021.08.21 |
[C++] 백준 3190번 뱀 풀이 (0) | 2021.08.21 |
[C++] 백준 2565번 전깃줄 풀이 (0) | 2021.08.17 |