문제출처
https://www.acmicpc.net/problem/14499
in Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.StringTokenizer; public class Main { static int n,m,x,y,k; static int[][] map; static int[] dice; static int[] dxs= {0,0,0,-1,1};// 동, 서, 북, 남 static int[] dys= {0,1,-1,0,0}; static int up,front,right; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); n=Integer.parseInt(st.nextToken()); m=Integer.parseInt(st.nextToken()); x=Integer.parseInt(st.nextToken()); y=Integer.parseInt(st.nextToken()); k=Integer.parseInt(st.nextToken()); dice= new int[]{0,0,0,0,0,0,0}; up=1; front=2; right=3; // 1. 격자 맵 입력받기 map=new int[n][m]; for (int i = 0; i < n; i++) { st=new StringTokenizer(br.readLine()); for (int j = 0; j < m; j++) { map[i][j]=Integer.parseInt(st.nextToken()); } } // 2. 이동하는 명령 입력받기 st=new StringTokenizer(br.readLine()); for (int i = 0; i < k; i++) { int inputNum= Integer.parseInt(st.nextToken()); // 3. 주사위 이동 diceMove(inputNum); } } public static void diceMove(int inputNum) { int nx=x+dxs[inputNum]; int ny=y+dys[inputNum]; // 1.1 주사위 이동 가능 if(canMove(nx,ny)) { // 2.1. 주사위 회전 // 동쪽으로 이동 if (inputNum==1) { int temp=up; up=7-right; right=temp; } // 서쪽으로 이동 else if(inputNum==2) { int temp=up; up=right; right=7-temp; } // 북쪽으로 이동 else if(inputNum==3) { int temp=up; up=front; front=7-temp; } // 남쪽으로 이동 else if(inputNum==4){ int temp=up; up=7-front; front=temp; } // 3.1 이동할 칸에 0이 쓰여있는경우 -> 이동할 칸에 주사위 바닥에 쓰여있는 숫자 복사 if(map[nx][ny]==0) { map[nx][ny]=dice[7-up]; } // 3.2 이동할 칸에 0이 쓰여있지 않은 경우 -> 이동할 칸에 쓰여있는 숫자를 주사위 바닥에 복사, 칸에 쓰여있는 숫자는 0으로 변경 else { dice[7-up]=map[nx][ny]; map[nx][ny]=0; } // 2.4 주사위 윗면 출력 System.out.println(dice[up]); x=nx; y=ny; } // 1.2 이동불가 -> 해당 명령은 무시하고 다음 명령으로 넘어간다. } public static boolean canMove(int x, int y) { return x>=0 && x<n && y>=0 && y<m; } } /* * 초기 주사위 : 모든 면에 0이 적혀있다. * 이동한 칸에 쓰여있는 숫자가 0 -> 주사위 바닥에 쓰여있는 숫자가 칸에 복사된다. * 이동한 칸에 쓰여있는 숫자가 0이 아니면 -> 칸에 쓰여있는 숫자가 주사위 바닥에 복사, 칸에 쓰여있는 숫자는 0 * 이동할때마다 주사위 상단에 쓰여있는 숫자 출력하기 * 격자밖으로 이동하려고 하면 해당 명령 무시, 출력도 하면 안된다. * */ | cs |
주사위 회전 시
주사위의 윗면, 앞면, 오른쪽면을
각각 1,2,3 으로 숫자를 지정해준다.
그러면 필연적으로
아랫면, 뒷면, 왼쪽면은
각각 6, 5, 4가 되어야한다.
왜냐하면 일반적인 주사위는
마주보는 양면의 합이 7이 되어야하기 때문이다.
이를 이용하면
쉽게 문제를 풀 수 있다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int n,m,x,y,k;
static int[][] map;
static int[] dice;
static int[] dxs= {0,0,0,-1,1};// 동, 서, 북, 남
static int[] dys= {0,1,-1,0,0};
static int up,front,right;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n=Integer.parseInt(st.nextToken());
m=Integer.parseInt(st.nextToken());
x=Integer.parseInt(st.nextToken());
y=Integer.parseInt(st.nextToken());
k=Integer.parseInt(st.nextToken());
dice= new int[]{0,0,0,0,0,0,0};
up=1; front=2; right=3;
// 1. 격자 맵 입력받기
map=new int[n][m];
for (int i = 0; i < n; i++) {
st=new StringTokenizer(br.readLine());
for (int j = 0; j < m; j++) {
map[i][j]=Integer.parseInt(st.nextToken());
}
}
// 2. 이동하는 명령 입력받기
st=new StringTokenizer(br.readLine());
for (int i = 0; i < k; i++) {
int inputNum= Integer.parseInt(st.nextToken());
// 3. 주사위 이동
diceMove(inputNum);
}
}
public static void diceMove(int inputNum) {
int nx=x+dxs[inputNum];
int ny=y+dys[inputNum];
// 1.1 주사위 이동 가능
if(canMove(nx,ny)) {
// 2.1. 주사위 회전
// 동쪽으로 이동
if (inputNum==1) {
int temp=up;
up=7-right;
right=temp;
}
// 서쪽으로 이동
else if(inputNum==2) {
int temp=up;
up=right;
right=7-temp;
}
// 북쪽으로 이동
else if(inputNum==3) {
int temp=up;
up=front;
front=7-temp;
}
// 남쪽으로 이동
else if(inputNum==4){
int temp=up;
up=7-front;
front=temp;
}
// 3.1 이동할 칸에 0이 쓰여있는경우 -> 이동할 칸에 주사위 바닥에 쓰여있는 숫자 복사
if(map[nx][ny]==0) {
map[nx][ny]=dice[7-up];
}
// 3.2 이동할 칸에 0이 쓰여있지 않은 경우 -> 이동할 칸에 쓰여있는 숫자를 주사위 바닥에 복사, 칸에 쓰여있는 숫자는 0으로 변경
else {
dice[7-up]=map[nx][ny];
map[nx][ny]=0;
}
// 2.4 주사위 윗면 출력
System.out.println(dice[up]);
x=nx; y=ny;
}
// 1.2 이동불가 -> 해당 명령은 무시하고 다음 명령으로 넘어간다.
}
public static boolean canMove(int x, int y) {
return x>=0 && x<n && y>=0 && y<m;
}
}
/*
* 초기 주사위 : 모든 면에 0이 적혀있다.
* 이동한 칸에 쓰여있는 숫자가 0 -> 주사위 바닥에 쓰여있는 숫자가 칸에 복사된다.
* 이동한 칸에 쓰여있는 숫자가 0이 아니면 -> 칸에 쓰여있는 숫자가 주사위 바닥에 복사, 칸에 쓰여있는 숫자는 0
* 이동할때마다 주사위 상단에 쓰여있는 숫자 출력하기
* 격자밖으로 이동하려고 하면 해당 명령 무시, 출력도 하면 안된다.
* */
in Python
주사위 굴리기...
배열에 모든 경우의 수를 다 적었던...
(미련한 뻘짓이었다!)
주사위 모양
2
4 1 3
5
6
1이 윗면
6이 아랫면
1. 동쪽
: 동쪽 이동시에는 4,1,3,6번째만 계속 움직이고
2와 5는 망부석
1번 자리에는 4번이 오고
4번 자리에는 6번이 오고
6번 자리에는 3번이 오고
3번 자리에는 1번이 오게 된다.
하지만 dice[1],dice[2]...dice[6]의 값만 바뀌는거지
상대적인 위치는 그대로!
dice[1]은 윗면, dice[6]은 아랫면
2. 서쪽
: 서쪽 이동시에도 동쪽과 마찬가지로 4,1,3,6번째만 계속 움직인다.
1번 자리에는 3번이 오고
3번 자리에는 6번이 오고
6번 자리에는 4번이 오고
4번 자리에는 1번이 온다.
3. 북쪽
: 북쪽 이동시엔 2,1,5,6번째만 계속 움직인다.
4,3번째는 망부석
2번 자리에는 1번이
1번 자리에는 5번이
5번 자리에는 6번이
6번 자리에는 2번이 온다.
4. 남쪽
: 남쪽 이동시엔 2,1,5,6번째만 계속 움직인다.
1번 자리에는 2번이
5번 자리에는 1번이
6번 자리에는 5번이
2번 자리에는 6번이 온다.
n, m, x, y, k = map(int, input().split())
# 동,서,북,남 = 1,2,3,4
dx = [0,0, 0, -1, 1]
dy = [0,1, -1, 0, 0]
array = [list(map(int, input().split())) for _ in range(n)]
moves = list(map(int, input().split()))
dice = [0, 0, 0, 0, 0, 0, 0] # 1,2,3,4,5,6(1이 윗면, 6이 바닥면)
top = 0
def moveDice(dir):
if dir == 1: # 동쪽
dice[1], dice[4], dice[3], dice[6] = dice[4], dice[6], dice[1], dice[3]
elif dir == 2: # 서쪽
dice[1], dice[3], dice[6], dice[4] = dice[3], dice[6], dice[4], dice[1]
elif dir == 3: # 북쪽
dice[1], dice[5], dice[6], dice[2] = dice[5], dice[6], dice[2], dice[1]
else: # 남쪽
dice[1], dice[2], dice[6], dice[5] = dice[2], dice[6], dice[5], dice[1]
def check(nx,ny):
if array[nx][ny] == 0:
array[nx][ny] = dice[6]
else:
dice[6] = array[nx][ny]
array[nx][ny]=0
'''
동쪽이동시
4 1 3 6 -> 6 4 1 3
서쪽이동시
4 1 3 6 -> 1 3 6 4
북쪽이동시
2 1 5 6 -> 1 5 6 2
남쪽이동시
2 1 5 6 -> 6 2 1 5
'''
for move in moves:
nx = x + dx[move]
ny = y + dy[move]
if 0 <= nx < n and 0 <= ny < m:
x=nx
y=ny
if move == 1: # 동쪽
moveDice(move)
check(nx,ny)
print(dice[1])
elif move == 2: # 서쪽
moveDice(move)
check(nx, ny)
print(dice[1])
elif move == 3: # 북쪽
moveDice(move)
check(nx, ny)
print(dice[1])
else: # 남쪽
moveDice(move)
check(nx,ny)
print(dice[1])
'여니의 취준 준비 > 코딩테스트 (Python)' 카테고리의 다른 글
[16956] 늑대와 양 in python (0) | 2022.01.14 |
---|---|
[스프링 핵심 원리 이해 1] 회원 도메인 설계 및 개발 (0) | 2022.01.09 |
[1520] 내리막 길 in python (0) | 2022.01.08 |
[1309] 동물원 in python (0) | 2022.01.08 |
[2644] 촌수 계산하기 in python (0) | 2022.01.08 |