주사위 굴리기 14499
1. 가장 처음에 주사위는 모든 면에 0 이 적혀있다.
2. 지도의 칸에는 정수가 쓰여있는데, 주사위가 이동하여 도착한 칸이
2-1. 수가 0이면, 주사위의 바닥면의 수가 칸에 복사된다.
2-2. 수가 0이 아니면, 칸의 수가 주사위의 바닥면으로 복사된다. (그 후, 칸의 수는 0이 된다.)
구하는 것 : (x, y) 와 이동 명령이 있을 때, 이동 시 마다의 주사위 상단의 값을 출력한다.
주의사항 :
- 지도의 바깥은 안되며, 바깥으로 가는 명령은 무시. 출력 x
- 처음 시작점의 쓰인 수는 항상 0이다.
- 칸의 수는 0 또는 10 미만의 자연수이다.
틀렸던 풀이 코드
#include <iostream>
#include <algorithm>
#include <vector>
#include <deque>
using namespace std;
// 14499 주사위 굴리기
int n, m, x, y, k;
bool checkCoord(int x, int y){
if(x >= 0 && x < n && y >= 0 && y < m) {
return true;
}
return false;
}
// flag 가 1이면 정방향 -1이면 역방향
void push(vector<int>& vec, int flag){
if(flag == 1){
int end = vec[vec.size() - 1];
for(int i = 0; i < vec.size() - 1; i++){
vec[i + 1] = vec[i];
}
vec[0] = end;
return;
}
else{
int start = vec[0];
for(int i = 0; i < vec.size() - 1; i++){
vec[i] = vec[i + 1];
}
vec[vec.size() - 1] = start;
}
}
int main(){
//
cin >> n >> m >> x >> y >> k;
vector<vector<int>> board(n, vector<int>(m, 0));
vector<int> orders(k, 0);
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
cin >> board[i][j];
}
}
for(int i = 0; i < k; i++)
cin >> orders[i];
vector<int> diceRow(3, 0);
vector<int> diceColumn(4, 0);
// 주사위 맨 윗 면은 diceRow[1] = diceColumn[1]
// 주사위 맨 뒷 면은 diceColumn[3]
vector<int>& upDown = {diceRow[0], diceRow[1], diceRow[2], diceColumn[3]};
int upperBound = 3;
int lowerBound = 2;
int currentX = x;
int currentY = y;
for(int order : orders){
// 동쪽
if(order == 1){
currentX = currentX;
currentY = currentY + 1;
if(!checkCoord(currentX, currentY)) continue;
push(diceRow, -1);
diceColumn[1] = diceRow[1];
upperBound = ( upperBound + 1 ) % 4;
lowerBound = ( lowerBound + 1 ) % 4;
}
// 서쪽
else if(order == 2){
currentX = currentX;
currentY = currentY - 1;
if(!checkCoord(currentX, currentY)) continue;
push(diceRow, 1);
diceColumn[1] = diceRow[1];
}
// 남쪽
else if(order == 4){
currentX = currentX + 1;
currentY = currentY;
if(!checkCoord(currentX, currentY)) continue;
push(diceColumn, -1);
diceRow[1] = diceColumn[1];
}
// 북쪽
else if(order == 3){
currentX = currentX - 1;
currentY = currentY;
if(!checkCoord(currentX, currentY)) continue;
push(diceColumn, 1);
diceRow[1] = diceColumn[1];
}
if(board[currentX][currentY] == 0){
board[currentX][currentY] = upDown[lowerBound];
}
else{
upDown[lowerBound] = board[currentX][currentY];
board[currentX][currentY] = 0;
}
cout << diceColumn[1] << '\n';
}
}
- 동 / 서 로 이동할 때는 단면도의 row 방향만 바뀌고 북 / 남으로 이동할 때는 단면도의 column 방향만 바뀌는 것으로 잘못 생각하여 구현한 코드이다.
문제는 결국, 처음 노트에서 시작된다. 검증없이 추상적인 아이디어로만 코드 구현에 돌입하면 이와 같은 돌이킬 수 없는 실수가 발생한다. 이런 실수는 갈아엎는 수 밖에는 고칠 수 없으니, 처음 문제를 접근할 때 가장, 신중해야 한다.
풀이 코드
#include <iostream>
#include <algorithm>
#include <vector>
#include <deque>
using namespace std;
// 14499 주사위 굴리기
int n, m, x, y, k;
bool checkCoord(int x, int y){
if(x >= 0 && x < n && y >= 0 && y < m) {
return true;
}
return false;
}
int main(){
//
cin >> n >> m >> x >> y >> k;
vector<vector<int>> board(n, vector<int>(m, 0));
vector<int> orders(k, 0);
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
cin >> board[i][j];
}
}
for(int i = 0; i < k; i++)
cin >> orders[i];
int currentX = x;
int currentY = y;
vector<int> dice(7, 0);
for(int order : orders){
int nextX, nextY;
// 동쪽
if(order == 1){
nextX = currentX;
nextY = currentY + 1;
if(!checkCoord(nextX, nextY)) continue;
int temp = dice[1];
dice[1] = dice[4];
dice[4] = dice[6];
dice[6] = dice[3];
dice[3] = temp;
}
// 서쪽
else if(order == 2){
nextX = currentX;
nextY = currentY - 1;
if(!checkCoord(nextX, nextY)) continue;
int temp = dice[1];
dice[1] = dice[3];
dice[3] = dice[6];
dice[6] = dice[4];
dice[4] = temp;
}
// 남쪽
else if(order == 4){
nextX = currentX + 1;
nextY = currentY;
if(!checkCoord(nextX, nextY)) continue;
int temp = dice[1];
dice[1] = dice[2];
dice[2] = dice[6];
dice[6] = dice[5];
dice[5] = temp;
}
// 북쪽
else if(order == 3){
nextX = currentX - 1;
nextY = currentY;
if(!checkCoord(nextX, nextY)) continue;
int temp = dice[1];
dice[1] = dice[5];
dice[5] = dice[6];
dice[6] = dice[2];
dice[2] = temp;
}
if(board[nextX][nextY] == 0){
board[nextX][nextY] = dice[6];
}
else{
dice[6] = board[nextX][nextY];
board[nextX][nextY] = 0;
}
cout << dice[1] << '\n';
currentY = nextY;
currentX = nextX;
}
}
해설
적용한 레시피 / 방법론 + 접근법
풀이
1. 주사위의 정보를 어떻게 저장할 것인가.
- 면에 번호를 메긴다.
2. 동 / 서 / 북 / 남에 대해서 주사위의 정보가 어떻게 변화하는가.
- 모든 경우에 대해서 어떻게 변하는지 직접 생각해서 식을 만들어낸다.
아쉬웠던 부분 / 오답 원인 / 개선해야 할 점
1. 주사위가 움직일 때의 주사위의 정보의 변화를 "이렇지 않을까?" 라는 생각만을 가지고 코드 구현에 돌입한 점.
- 맨 위의 코드는, 동 / 서 로 이동할 때는 단면도의 row 방향만 바뀌고 북 / 남으로 이동할 때는 단면도의 column 방향만 바뀌는 것으로 잘못 생각하여 구현한 코드이다.
문제는 결국, 처음 노트에서 시작된다. 검증없이 추상적인 아이디어로만 코드 구현에 돌입하면 이와 같은 돌이킬 수 없는 실수가 발생한다. 이런 실수는 갈아엎는 수 밖에는 고칠 수 없으니, 처음 문제를 접근할 때 가장, 신중해야 한다.
'ps > 구현' 카테고리의 다른 글
[프로그래머스] 신규 아이디 추천 (2021 카카오 블라인드 채용) (0) | 2022.02.04 |
---|---|
[구현] 로봇 청소기 14503 (0) | 2021.10.09 |
[구현] 톱니바퀴 14891 (0) | 2021.10.06 |
[구현] 배열 돌리기 1 16926 (0) | 2021.10.04 |
[구현] 16935 배열 돌리기 3 (0) | 2021.10.04 |