https://school.programmers.co.kr/learn/courses/30/lessons/60059#
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
이문제는 레벨3 문제치고는 쉬운 구현문제입니다.
기억해야할점
첫번쨰. 여기서 Lock의 길이인 N을 넣었어야햇는데 M을 넣어서 오랫동안 해맸습니다.
그냥 직관적으로 N, M 하지말고 lock.length로 하는것이 좋아보입니다.
//Board의 lock부분쪽을 다시 lock으로 초기화시킵니다.
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
Board[(M-1)+i][(M-1)+j] = Lock[i][j];
}
}
두번쨰, M은 항상 N 이하입니다.
이 조건을 처음에 못봐서 M이 큰 경우, N이 큰경우를 나눠서 구현하는중에 봤습니다.
세번쨰, 자물쇠와 열쇠를 새로 구현해줄떄 N + (M-1)*2 를 생각해낼떄 살짝 어려움이 있을 수 있습니다.
자물쇠를 한번 더하고 (열쇠 크기-1)의 크기를 2번 더한다고 쉽게 생각합니다.
그림으로 확인해보면 쉬어집니다.
Board = new int[ N + (M-1)*2][ N + (M-1)*2];
코드입니다.
class Solution {
int N;
int M;
int[][] Board;
int[][] temp;
int[][] Lock;
int[][] Key;
public boolean solution(int[][] key, int[][] lock) {
boolean answer = true;
N = lock.length;
M = key.length;
Lock = lock;
Key = key;
//자물쇠가 더 큰경우(M은 항상 N이하이다..)
Board = new int[ N + (M-1)*2][ N + (M-1)*2];
temp = new int[ N + (M-1)*2][ N + (M-1)*2];
//Board의 lock부분쪽을 다시 lock으로 초기화시킵니다.
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
Board[(M-1)+i][(M-1)+j] = Lock[i][j];
}
}
for(int k=0;k<Board.length;k++){
for(int h=0;h<Board[k].length;h++){
System.out.print(" "+Board[k][h]);
}
System.out.println();
}
System.out.println();
//반복문을 돌면서 각각 겹치는 구간 반복문을 모두 돕니다.
for(int rotate=0;rotate<4;rotate++){
for(int i=0;i< N + (M-1);i++){
for(int j=0;j< N + (M-1) ;j++){
//simulate에서 Board의 lock부분이 모두 1인지 확인합니다.
if(simulate(i, j) == true){
System.out.println("i:"+i+"j:"+j);
return true;
}
}
}
rotateBoard();
}
return false;
}
public boolean simulate(int startrow, int startcol){
//Board의 부분에 Key의 모든값을 다 더합니다.
for(int i=0; i<M; i++){
for(int j=0; j<M; j++){
Board[startrow+i][startcol+j] += Key[i][j];
}
}
//Board의 자물쇠 부분이 모두 1인지 확인합니다.
if(check() == true)
return true;
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
Board[(M-1)+i][(M-1)+j] = Lock[i][j];
}
}
return false;
}
public boolean check(){
int count = 0;
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
//0이거나 2이상이라면 바로 끝임.
if(Board[i+(M-1)][j+(M-1)] != 1){
return false;
}
}
}
return true;
}
public void rotateBoard(){
for(int i=0;i<M;i++){
for(int j=0;j<M;j++){
temp[i][j] = Key[i][j];
}
}
for(int i=0;i<M;i++){
for(int j=0;j<M;j++){
Key[j][M-i-1] = temp[i][j];
}
}
}
}
기억해야할점
첫번째, 홈끼리 만나면 안되기에 lock[][]은 모두 1 이어야만합니다. (0 이거나 2, 3, 4, 1 초과인경우 돌기가 서로 만나기에 맞지 않습니다.)
-자물쇠 영역 내에서는 열쇠의 돌기 부분과 자물쇠의 홈 부분이 정확히 일치해야 하며 열쇠의 돌기와 자물쇠의 돌기가 만나서는 안됩니다. 또한 자물쇠의 모든 홈을 채워 비어있는 곳이 없어야 자물쇠를 열 수 있습니다.
if(newLock[i][j] == 0 || newLock[i][j] > 1){
return false;
}
or
if(newLock[i][j] != 1){
return false;
}
두번째 코드입니다.
class Solution {
int[][] Key;
int[][] Lock;
int[][] newLock;
int lockLength = 0;
public boolean solution(int[][] key, int[][] lock) {
newLock = new int[key.length + key.length + lock.length - 2][key.length + key.length + lock.length - 2];
Key = key;
Lock = lock;
for(int i=0;i<lock.length;i++){
for(int j=0;j<lock.length;j++){
newLock[i+key.length-1][j+key.length-1] = lock[i][j];
}
}
// for(int i=0;i<key.length + key.length + lock.length - 2; i++){
// for(int j=0;j<key.length + key.length + lock.length - 2; j++){
// System.out.print(" "+newLock[i][j]);
// }
// System.out.println();
// }
// System.out.println();
//각회전방향마다 다 돌면서.
for(int rotate=0;rotate<4;rotate++){
rotatekey();
for(int j=0;j<=newLock.length - Key.length; j++){
// System.out.println("hekko?");
for(int k=0;k<=newLock.length - Key.length; k++){
// System.out.println("hekko?");
for(int h=0;h<Key.length;h++){
for(int q=0;q<Key.length;q++){
newLock[j+h][k+q] += Key[h][q];
}
}
// System.out.println("hekko?");
if(check() == true){
return true;
}
for(int h=0;h<Key.length;h++){
for(int q=0;q<Key.length;q++){
newLock[j+h][k+q] -= Key[h][q];
}
}
}
}
}
return false;
}
void rotatekey(){
int[][] newkey = new int[Key.length][Key.length];
for(int i=0;i<Key.length;i++){
for(int j=0;j<Key.length;j++){
newkey[j][Key.length - 1 - i] = Key[i][j];
}
}
Key = newkey;
// for(int i=0;i<Key.length;i++){
// for(int j=0;j<Key.length;j++){
// System.out.print(" "+Key[i][j]);
// }
// System.out.println();
// }
// System.out.println();
}
boolean check(){
// for(int i=0;i<Key.length + Key.length + Lock.length - 2; i++){
// for(int j=0;j<Key.length + Key.length + Lock.length - 2; j++){
// System.out.print(" "+newLock[i][j]);
// }
// System.out.println();
// }
// System.out.println();
for(int i=Key.length - 1;i < Key.length - 1 + Lock.length;i++){
for(int j=Key.length - 1;j < Key.length - 1 + Lock.length; j++){
if(newLock[i][j] == 0 || newLock[i][j] > 1){
return false;
}
}
}
return true;
}
}
'알고리즘 > 프로그래머스' 카테고리의 다른 글
[카카오 기출 문제]블록 이동하기 - 레벨 3, BFS (1) | 2023.01.06 |
---|---|
[카카오 기출 문제]불량 사용자- 레벨 3, 해쉬 + 이중해쉬 + 순열 + 조합 (0) | 2022.12.15 |
[카카오 기출 문제]합승 택시 요금- 레벨 3, 다익스트라 + 완전탐색 + 아이디어 + 그래프 (0) | 2022.11.17 |
[카카오 기출 문제]광고 삽입- 레벨 3, 아이디어 + 윈도우 슬라이딩 (0) | 2022.11.15 |
[카카오 기출 문제]다단계 칫솔 판매- 레벨 3, 링크드리스트 + 트리 + 노드 (0) | 2022.11.13 |