개빡세다.
특히
같이 key의 순차적인 탐색을 어떻게 하면 좀더 예쁘게 할 수 있을까....
답은 LOCK을 KEY의 탐색까지 덮히는 범위의 board를 만들어 준다.
이렇게 말이다.
그리고 board[][]의 가운데에 lock[][]을 넣어줘야 한다.
즉, board[m-1][m-1] ~ board[m+n-2] 에다가 lock[0][0] ~ lock[n-1][n-1]을 넣어준다.
여기서 조금 더 쉽게 넣는방법으로 for문 안에 변수를 2개씩 넣어주는 테크닉이 있다.
이것은 56~62번째 줄에 된다.
key의 rotate는 정사각형이니깐 쉬워서 넘어간다.
그다음 key 를 0 ~ m+n-2 부터 탐색하면서 xor을 하고 board에서 lock 부분이 전부 1이면 자물쇠가 맞는것이다.
이 과정은 gogo 함수 이다.
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
#include <iostream>
#include <vector>
#include <algorithm>
#define pii pair<int, int>
using namespace std;
int m; // key
int n; // lock
int board_size; // 2 * m + n - 2;
vector<vector<int>> rotate(vector<vector<int>> key)
{
vector<vector<int>> key2;
for (int i = 0; i < key[0].size(); i++)
{
vector<int> tmp;
for (int j = key.size() - 1; j >= 0; j--)
tmp.push_back(key[j][i]);
key2.push_back(tmp);
}
return key2;
}
bool gogo(int sx, int sy, vector<vector<int>> board, vector<vector<int>> key)
{
for (int i = 0; i < key.size(); i++)
{
for (int j = 0; j < key.size(); j++)
{
board[i + sx][j + sy] = (board[i + sx][j + sy] ^ key[i][j]);
}
}
int cnt = 0;
for (int i = m - 1; i < m + n - 1; i++)
{
for (int j = m - 1; j < m + n - 1; j++)
{
cnt += board[i][j];
}
}
if (cnt == n * n)
return true;
else
return false;
}
bool solution(vector<vector<int>> key, vector<vector<int>> lock)
{
m = key.size();
n = lock.size();
board_size = 2 * m + n - 2;
vector<vector<int>> board(board_size, vector<int>(board_size, 0));
// lock 의 가운데는 m-1 ~ m+n-2 이다.
for (int i = 0, ii = m - 1; ii < m + n - 1; i++, ii++)
{
for (int j = 0, jj = m - 1; jj < m + n - 1; j++, jj++)
{
board[ii][jj] = lock[i][j];
}
}
/*
for (int i = 0; i < board.size(); i++)
{
for (int j = 0; j < board[0].size(); j++)
cout << board[i][j] << ' ';
cout << '\n';
}
*/
vector<vector<int>> key2 = rotate(key);
vector<vector<int>> key3 = rotate(key2);
vector<vector<int>> key4 = rotate(key3);
// lock 의 가운데는 m-1 ~ m+n-2 이다.
// total 거리는 2 * m + n - 2;
for (int i = 0; i <= m + n - 2; i++)
{
for (int j = 0; j <= m + n - 2; j++)
{
if (gogo(i, j, board, key))
return true;
if (gogo(i, j, board, key2))
return true;
if (gogo(i, j, board, key3))
return true;
if (gogo(i, j, board, key4))
return true;
}
}
return false;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
vector<vector<int>> key = { {0,0,0}, {1,0,0}, {0,1,1} };
vector<vector<int>> lock = { {1,1,1}, {1,1,0}, {1,0,1} };
cout <<solution(key, lock);
}
|
cs |
'뚝배기 터진 문제_programmers' 카테고리의 다른 글
LV3_보행자 천국 (0) | 2020.09.08 |
---|---|
lv3 순위 (0) | 2020.09.06 |
lv3 N으로 표현. (0) | 2020.09.05 |
lv2 후보키 (0) | 2020.09.05 |
lv2 가장 큰 정사각형 찾기 (0) | 2020.09.05 |