[프로그래머스]Level3 - 자물쇠와 열쇠

 
by 박신종

> 문제

2020 카카오 블라인드 채용 문제 문제 : [자물쇠와 열쇠]


> 풀이

좌물쇠의 크기를 열쇠가 최소 한블럭이 걸칠 수 있도록 구현하였다.

전체 맵의 크기는 N + (M-1)*2

(0,0) 부터 (맵크기 - M + 1, 맵크기 - M + 1) 까지 키를 90도씩 돌려놓고 탐색하였다.

그리고, 위의 전체 맵에서 좌물쇠 범위(위 배열에서 1로 되어있는 부분)만 체크하였다.

소스는 다음과 같다.

package level3;
public class Solution_자물쇠와열쇠 {
	public static void main(String[] args) {
		int[][] key = {{0,0,0},{1,0,0},{0,1,1}};
		int[][] lock = {{1,1,1},{1,1,0},{1,0,1}};
		System.out.println(solution(key, lock));
	}
	// 키 회전을 위한 메소드
	static int[][] rotation(int[][] lock, int degree) {
		if(degree == 0) return lock;
		int N = lock.length;
		int[][] newLock = new int[N][N];
		
		for(int i=0; i<N; i++) {
			for(int j=0; j<N; j++) {
				switch(degree) {
				case 90:
					newLock[i][j] = lock[N-1-j][i];
					break;
				case 180:
					newLock[i][j] = lock[N-1-i][N-1-j];
					break;
				case 270:
					newLock[i][j] = lock[j][N-1-i];
					break;
				}
			}
		}
		return newLock;
	}
	
	static public boolean solution(int[][] key, int[][] lock) {
		int M = key.length;
		int N = lock.length;
	
		int[][] map = new int[N+((M-1)*2)][N+((M-1)*2)];	
		
		for(int i=M-1, a=0; a<N; i++, a++) {
			for(int j=M-1, b=0; b<N; j++, b++) {
				if(lock[a][b] == 1) map[i][j] = 1;
			}
		}
		
		int[] degrees = {0, 90, 180, 270};
		for (int r = 0; r < 4; r++) {
			int[][] tmp = rotation(key, degrees[r]);
			for (int i = 0; i <= map.length - M; i++) {
				for (int j = 0; j <= map[i].length - M; j++) {
					if (check(map, tmp, i, j)) return true;
				}
			}
		}
		
        return false;
    }
	
	static boolean check(int[][] map, int[][] key, int x, int y) {
		boolean flag = true;
		int M = key.length;
		int N = map.length-((M-1)*2);
        // 전체 맵 부분 키 작업 해주고,
		for(int a=0; a<M; a++) {
			for(int b=0; b<M; b++) {
				map[a+x][b+y] += key[a][b];
			}
		}
        // 해당 좌물쇠 범위를 체크하고, 열수없다면 false 체크하고 멈춘다.
		label: for(int i=M-1, a=0; a<N; i++, a++) {
			for(int j=M-1, b=0; b<N; j++, b++) {
				if(map[i][j] != 1) {
					flag = false;
					break label;
				}
			}
		}
        // 키 작업했던 부분 초기화.
		for(int a=0; a<M; a++) {
			for(int b=0; b<M; b++) {
				map[a+x][b+y] -= key[a][b];
			}
		}
		return flag;
	}
}




문제 출처 : Programmers