티스토리 뷰

문제보러가기

 

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;
	}

}
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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
글 보관함