[Programmers] 60059번 - 자물쇠와 열쇠 [Java][C++]
[Programmers] 60059번 - 자물쇠와 열쇠 [Java][C++]
1. 아이디어
열쇠를 4방향(0°/90°/180°/270°)으로 회전시키며, 자물쇠 범위를 벗어나는 위치까지 포함해 가능한 모든 위치에 겹쳐본다. 겹친 결과 자물쇠 칸이 전부 정확히 1이 되면(홈과 돌기가 정확히 맞물리면) 열 수 있다고 판단했다. 범위를 벗어나는 열쇠 칸은 애초에 자물쇠 검사 대상이 아니므로 무시하면 된다.
2. 복잡도
| 시간복잡도 | 공간복잡도 |
|---|---|
| $O((N+M)^2 (N^2+M^2))$ | $O(M^2)$ |
$N$ =
lock한 변 길이, $M$ =key한 변 길이 ($M \le N$)
3. 코드
풀이 [Java][C++]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
class Solution {
static int n, m;
public boolean solution(int[][] key, int[][] lock) {
n = lock.length;
m = key.length;
for (int d = 0; d < 4; d++) {
for (int i = -m + 1; i < n; i++) {
for (int j = -m + 1; j < n; j++) {
attach(lock, key, i, j);
if (match(lock)) return true;
detach(lock, key, i, j);
}
}
key = rotate(key);
}
return false;
}
static int[][] rotate(int[][] key) {
int[][] res = new int[m][m];
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
res[i][j] = key[m - 1 - j][i];
}
}
return res;
}
static void attach(int[][] lock, int[][] key, int sr, int sc) {
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
if (sr + i < 0 || sr + i >= n || sc + j < 0 || sc + j >= n) continue;
lock[sr + i][sc + j] += key[i][j];
}
}
}
static void detach(int[][] lock, int[][] key, int sr, int sc) {
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
if (sr + i < 0 || sr + i >= n || sc + j < 0 || sc + j >= n) continue;
lock[sr + i][sc + j] -= key[i][j];
}
}
}
static boolean match(int[][] lock) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (lock[i][j] != 1) return false;
}
}
return true;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <vector>
using namespace std;
int n, m;
vector<vector<int>> rotate(vector<vector<int>>& key) {
vector<vector<int>> res(m, vector<int>(m));
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
res[i][j] = key[m - 1 - j][i];
}
}
return res;
}
void attach(vector<vector<int>>& lock, vector<vector<int>>& key, int sr, int sc) {
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
if (sr + i < 0 || sr + i >= n || sc + j < 0 || sc + j >= n) continue;
lock[sr + i][sc + j] += key[i][j];
}
}
}
void detach(vector<vector<int>>& lock, vector<vector<int>>& key, int sr, int sc) {
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
if (sr + i < 0 || sr + i >= n || sc + j < 0 || sc + j >= n) continue;
lock[sr + i][sc + j] -= key[i][j];
}
}
}
bool match(vector<vector<int>>& lock) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (lock[i][j] != 1) return false;
}
}
return true;
}
bool solution(vector<vector<int>> key, vector<vector<int>> lock) {
n = lock.size();
m = key.size();
for (int d = 0; d < 4; d++) {
for (int i = -m + 1; i < n; i++) {
for (int j = -m + 1; j < n; j++) {
attach(lock, key, i, j);
if (match(lock)) return true;
detach(lock, key, i, j);
}
}
key = rotate(key);
}
return false;
}
This post is licensed under CC BY 4.0 by the author.