티스토리 뷰
이문제는... 정말.. 코딩이 단순히 코드를 작성하는 게 아니라 문제를 정확히 이해하는 것에서부터 출발한다는 걸 알려주는 문제였다.. 결론 -> 문제를 잘 읽자!
문제풀이
-각 말의 위치와 방향을 저장하고 있는 kInfo [][] 배열과 체스판의 색상 정보를 담고 있는 map [][] 배열에 초기 정보를 받아 저장한다.
-추가로 각 말들이 움직였을 때 맵의 상태를 저장하는 moveMap [][] 배열을 만든다 해당 말보다 나중에 들어올 경우 쌓이고 그 말들이 함께 이동해야 하므로 moveMap은 Stack을 저장할 수 있도록 생성한다.
-Stack으로 저장하므로 해당 순번의 말이 나올 때까지 pop을 하면 해당 순번의 말 위에 쌓인 말까지 함께 꺼낼 수 있다.
-말의 이동방향으로의 칸의 색을 보고 어떻게 수행할지 판단한다.
-파란색 칸을 만날 경우 : 반대방향으로의 칸을 확인 -> 파란색||맵 밖 경우 : 방향만 바꾸고 원래 자리에 있는다.
-> 빨간색 경우 : 이동하고 이동한 말들은 순서를 거꾸로 한다.
-> 하얀색 경우 : 이동한다.
놓칠 수 있는 부분
-한 칸의 말이 4개 이상일 때 바로 루프를 빠져나올 수 있게 한다. ==4 (x) >=4 (o)
-파란색을 만날 경우에 반대방향도 고려를 해줘야 하기 때문에 파란색일 경우는 한번 더 확인을 해줘야 한다.
-빨간색 칸일 경우 원래 그 칸에 있는 말들은 내버려두고 이동한 말들의 순서만 바꿔야 한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Stack;
import java.util.StringTokenizer;
public class Main {
final static int E = 1;
final static int W = 2;
final static int N = 3;
final static int S = 4;
static Stack<Integer>[][] moveMap;
static int[][] kInfo;
static ArrayList<Integer> list;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
int[][] map = new int[n][n];
moveMap = new Stack[n][n];
kInfo = new int[k + 1][3];
int trun = 1;
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < n; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
moveMap[i][j] = new Stack<>();
}
}
for (int i = 1; i <= k; i++) {
st = new StringTokenizer(br.readLine());
kInfo[i][0] = Integer.parseInt(st.nextToken()) - 1;
kInfo[i][1] = Integer.parseInt(st.nextToken()) - 1;
kInfo[i][2] = Integer.parseInt(st.nextToken());
moveMap[kInfo[i][0]][kInfo[i][1]].push(i);
}
outer: while (true) {
if (trun > 1000) {
trun = -1;
break;
}
// kinfo에서 1번말부터 검색한다
for (int i = 1; i <= k; i++) {
// 해당말의 위치에 가서 리스트에 값이 담겨져있는지 확인한다
list = new ArrayList<>();
int x = kInfo[i][0];
int y = kInfo[i][1];
int dir = kInfo[i][2];
// pop을 통해 해당말이 나올때까지 담고
while (!moveMap[x][y].isEmpty()) {
if (moveMap[x][y].peek() == i) {
list.add(moveMap[x][y].pop());
break;
} else {
list.add(moveMap[x][y].pop());
}
}
// 해당말의 방향으로 한칸 이동함 맵의 색을 확인하여 수행한다
int[] resultArr;
resultArr = moveDir(dir, x, y);
x = resultArr[0];
y = resultArr[1];
int color;
if (x >= n || y >= n || x < 0 || y < 0) {
color = 2;
} else {
color = map[x][y];
}
switch (color) {
case 0:
white(x,y);
break;
case 1:
red(x,y);
break;
case 2:
if (dir == E)
dir = W;
else if (dir == W)
dir = E;
else if (dir == N)
dir = S;
else if (dir == S)
dir = N;
resultArr = moveDir(dir, kInfo[i][0], kInfo[i][1]);
x = resultArr[0];
y = resultArr[1];
//파란색이여서 반대방향 봤는데 또 파란색일 경우
if (x >= n || y >= n || x < 0 || y < 0 || map[x][y] == 2) {
for (int index = list.size() - 1; index >= 0; index--) {
int piece = list.get(index);
moveMap[kInfo[i][0]][kInfo[i][1]].push(piece);
}
} else if (map[x][y] == 1) {
red(x,y);
} else {
white(x,y);
}
kInfo[i][2] = dir;
break;
}
// 4개가 모이면 종료
if (moveMap[kInfo[i][0]][kInfo[i][1]].size() >= 4) {
break outer;
}
}
trun++;
}
System.out.println(trun);
}
static void white(int x, int y) {
for (int index = list.size() - 1; index >= 0; index--) {
int piece = list.get(index);
moveMap[x][y].push(piece);
kInfo[piece][0] = x;
kInfo[piece][1] = y;
}
}
static void red(int x,int y) {
for (int index = 0; index < list.size(); index++) {
int piece = list.get(index);
moveMap[x][y].push(piece);
kInfo[piece][0] = x;
kInfo[piece][1] = y;
}
}
static int[] moveDir(int dir, int x, int y) {
switch (dir) {
case E:
y++;
break;
case W:
y--;
break;
case N:
x--;
break;
case S:
x++;
break;
}
int[] resultArr = { x, y };
return resultArr;
}
}
'CS공부 > 알고리즘&문제풀이' 카테고리의 다른 글
[프로그래머스]해시:위장(java) (2) | 2020.07.29 |
---|---|
[프로그래머스]DP:N으로 표현(java) (0) | 2020.07.26 |
[프로그래머스]스택/큐:프린터(java) (0) | 2020.07.14 |
[프로그래머스]정렬:가장 큰 수(java) (0) | 2020.07.13 |
[프로그래머스]완전탐색:소수 찾기(java) (0) | 2020.07.08 |
- Total
- Today
- Yesterday
- OS
- 삼성 sw역량 테스트
- DP
- 백준
- Spring
- 프로그래머스
- 삼성 sw역량테스트
- git
- 알고리즘
- JavaScript
- programers
- websocket
- 채팅
- Baekjoon
- SWEA
- 정렬
- sockjs
- 자바
- 코딩테스트
- 최소 스패닝 트리
- 완전탐색
- 운영체제
- java
- BFS
- Oracle
- dfs
- Heap
- Stomp
- MST
- 분리 집합
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |