+1 2020 KAKAO BLIND RECRUITMENT 자물쇠와 열쇠

이동한·2023년 6월 27일
0

알고리즘 기출

목록 보기
13/22
class Solution {
    
    static int pad;
    
    public boolean solution(int[][] key, int[][] lock) {
        pad = key.length-1;
        
        for(int dx = 0; dx<pad+lock.length; dx++){
            // 행에서 움직이는방향
            for(int dy = 0; dy <pad+lock.length; dy++){
                // 열에서 움직이는 방향
                for(int r = 0; r<4; r++){
                    int[][] bigLock = new int[lock.length+key.length*2][lock.length+key.length*2];
                    // 확장된 자물쇠 만들기
                    for(int i=0; i<lock.length; i++){
                        for(int j=0; j<lock.length; j++){
                            bigLock[pad+i][pad+j] = lock[i][j];
                        }
                    }
                    match(bigLock,key,dx,dy,r);
                    if(check(bigLock,lock.length)) return true;
                }
            }
        }
        
        return false;
        
    }
    
    public void match(int[][]bigLock , int key[][],int x,int y, int r){
        int keySize = key.length;
        
        for(int i=0; i<key.length; i++){
            for(int j=0; j<key.length; j++){
                 switch(r){
                    case 0: 
                         bigLock[x+i][y+j] += key[i][j];
                         break;
                     case 1:
                         // 90도 회전시 행과 열의 관계
                         bigLock[x+i][y+j] += key[j][keySize-1-i];
                             break;
                     case 2:
                         // 180도 회전시 행과 열의 관계
                         bigLock[x+i][y+j] += key[keySize-1-i][keySize-1-j];
                             break;
                     case 3:
                         bigLock[x+i][y+j] += key[keySize-1-j][i];
                             break;
                 }
            }
        }
    }
    /**
     열쇠가 들어 맞는 경우는 0+1, 1+0 뿐이므로 
     돌기와 돌기 => 1+1=2, 홈과 홈 => 0+0 => 0이 자물쇠에 있다면 
     맞지 않는 것
    */
    public boolean check(int[][] bigLock, int lockSize){
        for(int i=0; i<lockSize; i++){
            for(int j=0; j<lockSize; j++){
                if(bigLock[pad+i][pad+j] != 1) return false;
            }
        }
        return true;
    }
}

2차원 배열 회전

두번째

class Solution {
    public boolean solution(int[][] key, int[][] lock) {
        int padSize = key.length -1;
        int newSize = padSize*2 + lock.length;
        int[][] newLock = new int[newSize][newSize];
        int zeroToFill = 0;
        
        // 키를 움직이면서 비교하기 위한 확장 배열 만들기
        for(int i=0; i<lock.length; i++){
            for(int j=0; j<lock.length; j++){
                newLock[padSize+i][padSize+j] = lock[i][j];
                
                // 채워야할 구멍수 파악
                if(lock[i][j]==0) zeroToFill++;
            }
        }
        
        // 키 이동 시켜가며 끼워보기 -> 키의 왼쪽 가장위 [0][0] 원소부터 비교 시작한다.
        for(int x=0; x<padSize+lock.length; x++){
            for(int y=0; y<padSize+lock.length; y++){
                // 키 돌려가며 꼽아보기
                for(int r =0; r<4; r++){
                    int[][] curKey = rotated(key,r,key.length);
                    int fitCnt =0;
                    for(int i=0; i<key.length; i++){
                        boolean flag = false;
                        for(int j=0; j<key.length; j++){
                            // 자물쇠 밖에서 비교하는 경우는 무시한다.
                            if((x+i)>padSize+lock.length-1 || (y+j)>padSize+lock.length-1
                              || (x+i)<padSize || (y+j)<padSize) continue;
                            
                            int curKeyVal = curKey[i][j];
                            int curLockVal = newLock[x+i][y+j];
                            
                            if(curKeyVal+curLockVal !=1){
                                flag = true;
                                break;
                            }
                            else{
                                if(curLockVal == 0) fitCnt++;
                            }
                        }
                        if(flag) break;
                    }
                    if(fitCnt == zeroToFill) return true;
                }
            }
        }
        
        return false;
    }
    
    public int[][] rotated(int[][] raw,int rot,int size){
        if(rot==0) return raw;
        
        int[][] tmp = new int[size][size];
        if(rot == 1){
            for(int i=0; i<size; i++){
                for(int j=0; j<size; j++){
                    tmp[i][j] = raw[size-1-j][i];
                }
            }
        }else if(rot == 2){
            for(int i=0; i<size; i++){
                for(int j=0; j<size; j++){
                    tmp[i][j] = raw[size-1-i][size-1-j];
                }
            }
        }else{
            for(int i=0; i<size; i++){
                for(int j=0; j<size; j++){
                    tmp[i][j] = raw[j][size-1-i];
                }
            }
        }
        return tmp;
    }
}
profile
Pragmatic, Productive, Positivist

0개의 댓글