[프로그래머스] 2020 KAKAO BLIND RECRUITMENT 자물쇠와열쇠
여러가지 전략이 있을것 같은데요… 실제 코테 당시 제가 풀었던 방식은 다음과 같습니다.
예를들어 key가 3 * 3짜리 배열이고, lock이 5 * 5 짜리 배열이라면, 확장버전의 lock인 extLock은 9 * 9 짜리 배열이 되어야 합니다.
즉 lock의 상하좌우에 3-1 = 2 만큼의 여백을 더 만들어 둔것이죠. 이렇게 하면 key가 lock을 살짝 걸쳐서 시도하는 경우도 모두 시도할 수 있습니다.
자세한 내용은 주석으로…
class Solution {
public boolean solution(int[][] key, int[][] lock) {
int n = lock.length;
int m = key.length;
int extN = n+2*m-2; // 상하좌우에 m-1을 두번 더해줍니다.
int[][] extLock = new int[extN][extN]; // 확장버전의 자물쇠 배열
for(int row = 0 ; row < n ; row++) {
for(int col = 0 ; col < n ; col++ ) {
extLock[row + m-1][col + m-1] = lock[row][col]; // 중앙에만 lock을 복사해줌
}
}
// key는 총 네 방향으로 로테이션 가능합니다
for(int fig = 0 ; fig < 4 ; fig++ ) {
// key의 맨 첫번째 원소가 들어갈 자리를 row, col로 정해주는 겁니다
for(int row = 0 ; row < n+m-1 ; row++) {
for(int col = 0 ; col < n+m-1 ; col++) {
// 그 자리에 key를 두고 lock과 합쳤을때의 결과를 merged에 담습니다
int[][] merged = merge(key, extLock, row, col);
// 자물쇠가 열렸는지 여부를 판단하고, 열렸다면 참을 반환합니다
if(isSolved(merged, n, m)) {
return true;
}
}
}
// 열리지 않았다면 키를 90도 회전시킵니다
rotate(key);
}
// 이 모든 시도에서 성공하지 못했다면 이 자물쇠는 열 수 없습니다!
return false;
}
// 키를 90도 회전시켜줄 메서드
static void rotate(int[][] key) {
int m = key.length;
int[][] rotated = new int[m][m];
for(int kCol = 0, rRow = 0 ; kCol < m ; kCol++, rRow++) {
for(int kRow = m-1 , rCol = 0 ; kRow >= 0 ; kRow--, rCol++) {
rotated[rRow][rCol] = key[kRow][kCol];
}
}
for(int row = 0 ; row < m ; row++) {
for(int col = 0 ; col < m ; col++) {
key[row][col] = rotated[row][col];
}
}
}
// 키와 자물쇠를 맞춰본 결과를 반환해줄 메서드
static int[][] merge(int[][] key, int[][] extLock, int row, int col){
int n = extLock.length;
int m = key.length;
int[][] res = new int[n][n]; // 빈 배열을 하나 만들어서
for(int i = 0 ; i < n ; i++) {
for(int j = 0 ; j < n ; j++ ) {
res[i][j] = extLock[i][j]; // extLock을 복사해온 뒤
}
}
for(int i = 0, r = row ; i < m ; i++, r++) {
for(int j = 0, c = col ; j < m ; j++, c++) {
res[r][c] += key[i][j]; // 키와 합쳐줍니다
}
}
return res;
}
// 자물쇠가 풀렸는지 여부를 반환해줄 매서드
static boolean isSolved(int[][] merged, int n, int m) {
for(int row = 0 ; row < n ; row++) {
for(int col = 0 ; col < n ; col++) {
// 1이 아니라면(0이거나 2라면) 풀린게 아님
if(merged[row+m-1][col+m-1] != 1)
return false;
}
}
}
return true;
}
}
Comments