회전
int[][][] gkey = new int[m][m][4];
여기에 0도,90,180도,270도의 key모양을 저장한다.
Rotation 구현은 다음과 같이 할 수 있다.
- 이 방법은, 별개의 메모리를 사용한다는 단점이 있었는데, 어차피 이 문제는, 각각의 모양을 저장 해 두고 풀어야 하기 때문에 괜찮다고 생각되었다.
Convolve
초반에 생각했던 것
Padding을 넣어주는게 훨씬 편한 방법이었다.
1이 돌기임. 0이 홈이고
자물쇠의 0에 열쇠의 1이 들어가야하고 —> 1
자물쇠의 1에 열쇠의 0 이 들어가야함. —> 1 ..
자물쇠의 0에 열쇠의 0 이 있거나, 자물쇠의 1에 열쇠의 1이 있음 안됨
이런 경우에는 XOR이지
Convolution 구현을 어떻게 할까??? —> 아예 커다란 2D 배열을 하나 할당해서 푸는게 더 낫다.
아래코드를 작성함 —> Runtime Error가 나왔는데 아주 사소한 이유였다.. 이유는..아래에
package test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class main {
public static int n,m;
public static int[][] glock;
public static int[][][] gkey;
public static void setKey(){
// 90도씩 회전시켜
// i 번째 도형을 회전시켜 저장한다.
/*
* row --> col.lengt() - row 로 변환된다.
* 어차피 각자의 memory를 이미 차지하고 있기 때문에.
* */
for(int i=0;i<3;i++){
for(int r =0;r<m;r++){
for(int c=0;c<m;c++){
gkey[i+1][c][m-1-r] = gkey[i][r][c];
}
}
}
}
public static boolean solution(int[][] key, int[][] lock) {
boolean answer = false;
n = lock.length;
m = key.length;
glock = lock;
// key를 ......
gkey = new int[4][m][m];
// 첫 번째 모양을 세팅
for(int r=0;r<lock.length;r++){
for(int c =0;c<lock[0].length;c++){
gkey[0][r][c]= key[r][c];
}
}
setKey();
answer = convolve();
return answer;
}
public static boolean convolve(){
int len = 2*m+n-2; // 7
int[][] sheet = new int[len][len];
int row = m-1, col = m-1;
for(int key=0;key<4;key++) {
// 맨 왼쪽 맨 위부터 key를 연산시킨다.전체를 XOR 연산 시키더라도, 마지막에는 중앙의 것만 확인하면 된다.
for (int r = 0; r <= len-m; r++) {
for (int c = 0; c <= len-m; c++) {
// 시트를 초기화 =====
// 중앙에 key를 재배치한다.(그 바깥은 상관 없다 ) --> 출력해 보니, 초기화는 잘된 거 맞음.
for(int lr=0;lr<n;lr++){
for(int lc=0;lc<n;lc++){
sheet[row+lr][col+lc]=glock[lr][lc];
}
}
// 매 번 (r,c)를 key 의 왼쪽 맨 위 꼭지점이라고 생각을 한다.
for(int kr=0;kr<m;kr++){
for(int kc=0;kc<m;kc++){
sheet[r+kr][c+kc] =(sheet[r+kr][c+kc] ^ gkey[key][kr][kc]);
}
}
// 해당 convolution 결과, 중앙의 key에 0 이 없다면 --> 성공이다
if(isLockOpen(sheet)) return true;
}
}
}
return false;
}
public static boolean isLockOpen(int[][] sheet){
int row = m-1, col = m-1;
// 중앙값만을 확인한다.
for(int lr=0;lr<n;lr++){
for(int lc=0;lc<n;lc++){
if(sheet[row+lr][col+lc]==0) return false;
}
}
return true;
}
public static void main(String[] args) throws IOException {
//Setting();
//boolean res = solution(new int[][]{{0, 0, 0}, {1, 0, 0}, {0, 1, 1}}, new int[][]{{1, 1, 1}, {1, 1, 0}, {1, 0, 1}});
//boolean res = solution(new int[][]{{0, 0, 0}, {1, 0, 0}, {0, 1, 1}}, new int[][]{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}});
boolean res = solution(new int[][]{{1}}, new int[][]{{0}});
System.out.println(res);
}
}
혹시나 해서...
// 첫 번째 모양을 세팅
for(int r=0;r<lock.length;r++){
for(int c =0;c<lock[0].length;c++){
gkey[0][r][c]= key[r][c];
}
}
기존의 윗 부분을 아래와 같이 변경하니 정답이 나왔다.
// 첫 번째 모양을 세팅
for(int r=0;r<m;r++){
for(int c =0;c<m;c++){
gkey[0][r][c]= key[r][c];
}
}