접근
https://www.acmicpc.net/problem/17780
문제에서 주어진 대로 구현만 하면 되는 단순 구현 문제였다. 백준에 삼성 관련 문제들이 이런 스타일인 것 같다.
문제의 키포인트는
- 맨 아래에 있는 말만 이동할 수 있다.
- 1번말부터 탐색하되 해당 말이 맨 아래에 있으면 이동하지 않고 넘어가면 된다.
- 하늘색 칸으로 이동 시 방향을 반대로 하고 1칸 이동하되, 반대쪽에도 하늘색 칸일 경우 방향만 바꾸고 제자리에 있는다. 맵 바깥으로 나가는 경우도 하늘색 칸에 도달한 것과 동일하게 계산한다.
- 목적 칸이 흰색일 경우 아래의 말부터 다음 칸으로 이동시키고, 빨간색일 경우 맨 위 말부터 다음 칸으로 이동시킨다.
위 포인트들에 주의하면서 풀면 쉽게 해결할 수 있다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
static class Horse {
int num, dir;
Horse(int num, int dir) {
this.num = num;
this.dir = dir;
}
}
static int N, K;
static int color[][], loc[][];
static LinkedList<Horse>[][] map;
static int[] dr = { 0, -1, 0, 1 };
static int[] dc = { 1, 0, -1, 0 };
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());
K = Integer.parseInt(st.nextToken());
// color[r][c]에 해당 칸의 색을 저장
color = new int[N][N];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
color[i][j] = Integer.parseInt(st.nextToken());
}
}
// loc[k][0], loc[k][1] 에 k번 말의 r, c 좌표 저장
loc = new int[K][2];
// map[r][c] 에 LinkedList를 만들어 말의 순서 정보 저장
map = new LinkedList[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
map[i][j] = new LinkedList<>();
}
}
int r, c, d;
for (int i = 0; i < K; i++) {
st = new StringTokenizer(br.readLine());
r = Integer.parseInt(st.nextToken()) - 1;
c = Integer.parseInt(st.nextToken()) - 1;
d = Integer.parseInt(st.nextToken()) - 1;
switch (d) {
case 1:
d = 2;
break;
case 2:
d = 1;
break;
default:
break;
}
loc[i][0] = r;
loc[i][1] = c;
map[r][c].add(new Horse(i, d));
}
br.close();
System.out.println(Solve());
}
static int Solve() {
for (int t = 1; t <= 1000; t++) {
for (int k = 0; k < K; k++) {
int r = loc[k][0];
int c = loc[k][1];
// k번 말이 맨 아래에 있지 않을 경우 continue
if (map[r][c].get(0).num != k) continue;
int d = map[r][c].get(0).dir;
int nr = r + dr[d];
int nc = c + dc[d];
// 다음 위치가 하늘색 칸 혹은 체스 판을 벗어날 경우
if (colorBlue(nr, nc)) {
d = (d + 2) % 4;
map[r][c].get(0).dir = d;
nr = r + dr[d];
nc = c + dc[d];
// 뒤돌아 한칸 이동한 위치도 하늘색 칸 혹은 체스 판을 벗어날 경우 continue
if (colorBlue(nr, nc)) {
continue;
}
}
// r, c 위치의 말들을 nr, nc 위치로 옮기고 해당 칸의 말의 수가 4 이상이면 t 리턴
if (moveAndCount(r, c, nr, nc) >= 4) {
return t;
}
}
}
// 1000회 이동하고도 조건에 만족하지 않으면 -1 리턴
return -1;
}
// r, c 위치가 하늘색 칸이거나 체스판 밖으로 나갔는지 판단하는 함수
static boolean colorBlue(int r, int c) {
return r < 0 || N <= r || c < 0 || N <= c || color[r][c] == 2;
}
// r, c 위치의 말을 nr, nc 위치로 옮기고 해당 칸의 말의 수를 리턴하는 함수
static int moveAndCount(int r, int c, int nr, int nc) {
if (color[nr][nc] == 0) {
while (map[r][c].size() > 0) {
Horse temp = map[r][c].pollFirst();
loc[temp.num][0] = nr;
loc[temp.num][1] = nc;
map[nr][nc].add(temp);
}
} else {
while (map[r][c].size() > 0) {
Horse temp = map[r][c].pollLast();
loc[temp.num][0] = nr;
loc[temp.num][1] = nc;
map[nr][nc].add(temp);
}
}
return map[nr][nc].size();
}
}
더 생각해 볼 것?
...
코드나 내용 관련 조언, 부족한 점 및 질문 언제든 환영합니다!
반응형
'코딩 > 백준 (JAVA)' 카테고리의 다른 글
백준 1800번: 인터넷 설치 (Java) (0) | 2022.07.02 |
---|---|
백준 16639번: 괄호 추가하기 3 (Java) (0) | 2022.07.02 |
백준 18500: 미네랄 2 (Java) (0) | 2022.06.29 |
백준 10021번: Watering the Fields (Java) (0) | 2022.06.25 |
백준 15591번: MooTube (Java) (0) | 2022.06.25 |
최근댓글