백준 1063 - 킹 (java)

J·2022년 9월 17일
0

알고리즘 문제풀이

목록 보기
8/21
post-custom-banner

문제 정리


보통 배열이 아니라 배열의 index에 이름이 있다 (A1, H2 등)
돌은 킹이 움직이려는 방향에 있을때만 같이 움직인다
만약 돌이나 킹이 움직이려는 곳이 배열 범위 밖이면 해당 명령어는 실행하지 않는다
명령어를 다 실행한 후의 돌과 킹의 위치를 구하는 것이 목표이다

입력

킹위치 돌위치 명령어수
명령어 한 줄에 하나씩

출력

킹위치
돌위치

idea 정리


동작을 나눠서 정확히 구현하는 것과
입력받은 위치를 어떻게 바꿔서 사용할 것인지가 중요한 문제이다

나는 입력받은 체스판의 index 형식을
배열의 index 형식으로 바꾸고 (r, c 형식)
명령어 수행이 끝나면 체스판의 index 형식으로 바꾸는 것이었다

즉, 체스판 형식 -> 배열 형식 -> 체스판 형식 으로 변환해준다

명령어들은 direction index로 바꿔서 사용하면 간단하게 정리했다
남은건 돌이 방향에 있는지, 배열의 범위를 넘어나는지 확인 후 이동하는 건데 direction 배열을 만들어 두면 어렵지 않다

알고리즘 정리


  1. 체스판 형식을 배열 형식으로 바꾸어 준다
  2. 움직이려는 방향에 돌이 있는지 확인한다
  3. 돌이 있으면 돌이 움직이려는 index가 범위를 벗어나는지 확인해본다
    킹도 움직이려는 index가 범위를 벗어나는지 확인해본다
    둘 다 범위가 벗어나지 않는다면 이동한다
  4. 명령어를 다 처리했다면 배열 형식을 체스판 형식으로 바꾸어 출력한다

구현


//킹
public class Main {
	static class Thing{
		int r, c;
		public Thing(int r, int c) {
			super();
			this.r = r;
			this.c = c;
		}
	}
	static Thing king, stone;
	static String[] cmds;
	static int N;
	static int[] dr = {0, -1, -1, -1, 0, 1, 1, 1};		//L, LT, T, RT, R, RB, B, LB
	static int[] dc = {-1, -1, 0, 1, 1, 1, 0, -1};
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		king = indexToThing(st.nextToken());
		stone = indexToThing(st.nextToken());
		N = Integer.parseInt(st.nextToken());
		
		cmds = new String[N];
		for(int i=0; i<N; i++) {
			String cmd = br.readLine();
			int direction = getDirection(cmd);
			boolean withStone = isThereStone(direction);
			move(direction, withStone);
		}
		
		String k = thingToIndex(king);
		String s = thingToIndex(stone);
		bw.write(k + "\n" + s);
		bw.flush();
		bw.close();
		br.close();
	}
	
	static Thing indexToThing(String index) {	//H1 -> r,c
		int c = index.charAt(0) - 'A';
		int r = 8 - (index.charAt(1) - '0');
		
		return new Thing(r, c);
	}
	static String thingToIndex(Thing thing) {   //r,c -> H1
		char c = (char)(thing.c + 'A');
		char r = (char)(8-thing.r + '0');
		
		StringBuilder sb = new StringBuilder();
		sb.append(c); sb.append(r);
		return sb.toString();
	}
	
	static int getDirection(String cmd) {
		switch(cmd) {
		case "L"	: return 0;
		case "LT" 	: return 1;
		case "T"	: return 2;
		case "RT"	: return 3;
		case "R"	: return 4;
		case "RB"	: return 5;
		case "B"	: return 6;
		default		: return 7;
		}
	}
	
	static boolean isThereStone(int direction) {	//가려는 방향에 돌이 있는지
		int nr = king.r + dr[direction];
		int nc = king.c + dc[direction];
		
		if(stone.r == nr && stone.c == nc) return true;		//가려는 방향에 돌이 있음
		return false;
	}
	
	//withStone->돌도 움직여야하나, direction -> 방향
	static void move(int direction, boolean withStone) {
		if(withStone) {		//돌도 움직여야 하는 경우
			int nr = stone.r + dr[direction];
			int nc = stone.c + dc[direction];
			
			if(nr<0 || 8<=nr || nc<0 || 8<=nc) {		//돌이 범위가 벗어남
				return;
			}
			stone.r = nr;
			stone.c = nc;
		}
		int nr = king.r + dr[direction];
		int nc = king.c + dc[direction];
		if(nr<0 || 8<=nr || nc<0 || 8<=nc) {		//킹이 범위가 벗어남
			return;
		}
		king.r = nr;
		king.c = nc;
	}
}

결과


post-custom-banner

0개의 댓글