티스토리 뷰
17837번: 새로운 게임 2
재현이는 주변을 살펴보던 중 체스판과 말을 이용해서 새로운 게임을 만들기로 했다. 새로운 게임은 크기가 N×N인 체스판에서 진행되고, 사용하는 말의 개수는 K개이다. 말은 원판모양이고, 하�
www.acmicpc.net
이문제는... 정말.. 코딩이 단순히 코드를 작성하는 게 아니라 문제를 정확히 이해하는 것에서부터 출발한다는 걸 알려주는 문제였다.. 결론 -> 문제를 잘 읽자!
문제풀이
-각 말의 위치와 방향을 저장하고 있는 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
 
- 정렬
 - BFS
 - OS
 - Baekjoon
 - SWEA
 - 삼성 sw역량테스트
 - websocket
 - dfs
 - 자바
 - git
 - 백준
 - 코딩테스트
 - JavaScript
 - 프로그래머스
 - 운영체제
 - Spring
 - 완전탐색
 - Stomp
 - Heap
 - DP
 - sockjs
 - 최소 스패닝 트리
 - Oracle
 - 삼성 sw역량 테스트
 - 알고리즘
 - MST
 - 채팅
 - programers
 - 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 |